想知道我是不是有内存泄漏(报告为潜在)
Posted
技术标签:
【中文标题】想知道我是不是有内存泄漏(报告为潜在)【英文标题】:Wondering do i have a mem leak(reported as potential)想知道我是否有内存泄漏(报告为潜在) 【发布时间】:2011-01-31 20:21:07 【问题描述】:我在我的 do-while 循环之外创建了一个名为 mutableScoreHolder 的 NSMutableString。 我分配它,将其“复制”到另一个名为“Match”的对象中,该对象包含一个 NSString。
当我构建和分析代码时,它会报告我的 mutableScoreHolder 的潜在内存泄漏。
NSString * scoreHolder;
NSMutableString * mutableScoreHolder;
count = 1;
numMatchCounter = 0;
int startOfScoreIndex = 0;
int endOfScoreIndex = 0;
int numberOfGoals=0;
do
match = [substring rangeOfString: @"points_bg"];
if (match.location == NSNotFound)
break;
if ((match.location + match.length) > ([substring length]))
break;
substring = [substring substringFromIndex:(match.location + match.length)];
match2 = [substring rangeOfString: @">"];
startOfScoreIndex = match2.location+1;
match2 = [substring rangeOfString: @"<"];
endOfScoreIndex = match2.location;
if ((count % 2) == 1)
scoreHolder = [substring substringWithRange:NSMakeRange(startOfScoreIndex, (endOfScoreIndex-startOfScoreIndex))];
mutableScoreHolder = [[NSMutableString alloc] initWithString:scoreHolder];
numberOfGoals += [scoreHolder intValue];
else
Match *aMatch = [theMatchScoresArray objectAtIndex:(numMatchCounter)];
numberOfGoals += [[substring substringWithRange:NSMakeRange(startOfScoreIndex, (endOfScoreIndex-startOfScoreIndex))] intValue];
[scoreHolder stringByAppendingString:@" - "];
[mutableScoreHolder appendString:@" - "];
[scoreHolder stringByAppendingString:[substring substringWithRange:NSMakeRange(startOfScoreIndex, (endOfScoreIndex-startOfScoreIndex))]];
[mutableScoreHolder appendString:[substring substringWithRange:NSMakeRange(startOfScoreIndex, (endOfScoreIndex-startOfScoreIndex))]];
aMatch.theScore = [mutableScoreHolder copy];
aMatch.matchGoalCount = numberOfGoals;
numMatchCounter++;
numberOfGoals=0;
count++;
while ( match.length != 0 );
这是我的匹配对象类。
@interface Match : NSObject
NSString *teamName1;
NSString *teamName2;
NSString *theScore;
int matchGoalCount;
NSMutableArray *scorersArray;
NSMutableArray *scorerOrderArray;
NSString *matchStatus;
NSString *matchDate;
bool matchNotStarted;
@property(nonatomic) int matchGoalCount;
@property(nonatomic) bool matchNotStarted;
@property(nonatomic, retain) NSString *teamName1;
@property(nonatomic, retain) NSString *teamName2;
@property(nonatomic, retain) NSString *theScore;
@property(nonatomic, retain) NSString *matchStatus;
@property(nonatomic, retain) NSString *matchDate;
@property(nonatomic, retain) NSMutableArray *scorersArray;
@property(nonatomic, retain) NSMutableArray *scorerOrderArray;
-(id)init;
@end
#import "Match.h"
@implementation Match
@synthesize teamName1;
@synthesize teamName2;
@synthesize theScore;
@synthesize scorersArray;
@synthesize matchDate;
@synthesize matchStatus;
@synthesize matchGoalCount;
@synthesize scorerOrderArray;
@synthesize matchNotStarted;
-(id)init
//NSLog(@"****** MATCH INIT ******");
self = [super init];
scorersArray =[[NSMutableArray alloc] init];
scorerOrderArray =[[NSMutableArray alloc] init];
return self;
-(void) dealloc
[scorersArray release];
[scorerOrderArray release];
[teamName1 release];
[teamName2 release];
[theScore release];
[matchStatus release];
[matchDate release];
[scorersArray release];
[scorerOrderArray release];
[super dealloc];
@end
当我运行仪器检查泄漏时,我确实发现有一个字符串泄漏。所以我认为这个“潜在的泄漏”可能就是我看到的泄漏。
因为分数有保留
@property(nonatomic, retain) NSString *theScore;
还有一个字符串复制到里面
aMatch.theScore = [mutableScoreHolder copy];
可以将保留计数设为 2 吗?那么泄漏呢?
抱歉这个复杂的问题!我的头在旋转,试图绕过它。
谢谢 -代码
【问题讨论】:
【参考方案1】:你肯定在这里泄漏,有两个不同的原因。
首先是你分配/初始化一个 NSMutableString 并将其填充到 mutableScoreHolder
中。这是一个局部变量,一旦这个值超出范围(或在下次创建新数组时被替换),旧值就会泄露。这应该是一个自动释放的值,如[NSMutableString stringWithString:scoreHolder]
。
第二个是复制字符串并将结果值填充到属性中。您应该做的是将该属性重新声明为副本
@property(nonatomic, copy) NSString *theScore;
然后直接将mutableScoreHolder
分配给该属性
aMatch.theScore = mutableScoreHolder
使用现有代码复制数组,然后属性会保留它。通过此更改,属性直接复制它,并且不使用额外的保留。
注意,一般来说,将支持类型的属性声明为copy
是个好主意。这包括 NSString、NSArray、NSDictionary 等。如果您将一个已经不可变的对象分配给该属性,则 copy
会回退到 retain
并且不会影响性能。但是在像您这样分配可变对象的情况下,它会根据需要复制它并在属性中保留不可变快照。
【讨论】:
嗨,Kevin,所以将匹配中的所有 NSString 和 NSMutableArray 从“保留”更改为“复制”是安全的,这样会更安全吗?我已经更改了 theScore 并且运行良好。谢谢 如果您有一个属性,其中类型是具有可变变体的不可变类(例如 NSString、NSArray、NSDictionary 等),使用copy
往往是个好主意。这需要类型支持 NSCopying,但所有看起来像这样的 Cocoa 类都支持复制。【参考方案2】:
还有一个字符串复制到里面
aMatch.theScore = [mutableScoreHolder copy];
这样可以吗 保留计数为 2?然后 泄漏?
没错。您可以将theScore
的属性从retain
更改为copy
来解决此问题。那么你可以使用aMatch.theScore = mutableScoreHolder;
并且(至少)还有另一个泄漏:
mutableScoreHolder = [[NSMutableString alloc] initWithString:scoreHolder];
这永远不会被释放。
【讨论】:
以上是关于想知道我是不是有内存泄漏(报告为潜在)的主要内容,如果未能解决你的问题,请参考以下文章