想知道我有内存泄漏(报告为潜在的)

时间:2011-01-31 20:21:07

标签: iphone objective-c

我在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吗?那么泄漏?

对不起这个复杂的问题!我的脑袋旋转着试图绕过它。

由于 -Code

2 个答案:

答案 0 :(得分:2)

你肯定在这里泄漏,原因有两个。

首先是你分配/初始化NSMutableString并将其填入mutableScoreHolder。这是一个局部变量,一旦该值超出范围(或在下次创建新数组时被替换),旧值就会泄漏。这应该是一个自动释放的值,如[NSMutableString stringWithString:scoreHolder]

第二个是你正在复制字符串并将结果值填充到属性中。您应该做的是将该属性重新声明为副本

@property(nonatomic, copy) NSString *theScore;

然后直接将mutableScoreHolder分配给该属性

aMatch.theScore = mutableScoreHolder

使用现有代码复制数组,然后属性保留它。通过此更改,属性将直接复制,并且不会使用额外的保留。

注意,一般来说,将支持类型的属性声明为copy是个好主意。这包括NSString,NSArray,NSDictionary等等。如果您正在为属性分配一个已经不可变的对象,copy会回退到retain,并且没有性能损失。但是在你和你分配可变对象的情况下,它会根据需要复制它,并在属性中保留一个不可变的快照。

答案 1 :(得分:0)

  

并且有一个字符串被复制到其中

aMatch.theScore = [mutableScoreHolder copy]; 
     

可能   保留计数为2?然后呢   泄漏?

准确。您可以将theScore的属性从retain更改为copy以解决此问题。你可以使用aMatch.theScore = mutableScoreHolder;

并且(至少)还有一个泄漏:

mutableScoreHolder = [[NSMutableString alloc] initWithString:scoreHolder];

这从未发布过。