内存泄漏:在iPhone应用程序中发布NSArray的问题

时间:2011-04-15 10:37:12

标签: iphone objective-c cocoa-touch ios4 nsarray

我有一个显示仪器泄漏的代码。它显示泄漏,我使用arrayDetPerformance

的内容初始化arrayDetail

如果我发布了arrayDetail,那么我的应用就会崩溃。

可能出现什么问题?

以下是代码:

    NSDictionary *finalResult = [extractUsers JSONValue];
    //      NSLog(@" Stamp-16 : %@",[NSDate date]);
    NSLog(@"Array2  : %d",[arrayDetail retainCount]);        //RETAIN COUNT IS 0
    arrayDetail = [[finalResult objectForKey:@"Detail"]
    NSLog(@"Array2  : %d",[arrayDetail retainCount]);       //RETAIN COUNT IS 2

    //  NSLog(@"Data is : %@",array1);
    //      NSLog(@" Stamp-17 : %@",[NSDate date]);

    //NSLog(@"Final Value is : %@",[[allUsers objectAtIndex:0] valueForKey:@"password"]);

    //[self setUserData:allUsers];
    //[tblView reloadData];

    [responseString release];
    [request release];

}



//sleep(0.3);
//[inProgressIndicator stopAnimating];
[fileContents release];

//Release all the allocated data
[json release];
//label.text = @"Finish";
//  NSLog(@" Stamp-19 : %@",[NSDate date]);
NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
//NSLog(@"Array2  : %d",[array2 retainCount]);

arrayDetPerformance = [[NSMutableArray alloc] initWithArray:arrayDetail];
chartPoints= [arrayDetPerformance valueForKey:@"Points"];
NSLog(@"Chart Points: %@",chartPoints);
[def setObject:chartPoints forKey:@"yarray"];
[def setObject:@"YES" forKey:@"flagThumb"];

//array1 = [[NSMutableArray  alloc] initWithObjects:@"New",@"Table",@"View",nil];
//[self.Dettable reloadData];
//sNSFileManager *fileManager = [NSFileManager defaultManager];
//[array2 release];
NSLog(@"ArrayDEtPerfomance : %d",[arrayDetPerformance retainCount]);
NSLog(@"array2 : %d",[arrayDetail retainCount]);
if([chartPoints count]>0)
{
    PlotItem *plotItem = [[PlotGallery sharedPlotGallery] objectAtIndex:0];
    [plotItem imageHive:Fund];
}

//[arrayDetail release];

}

内存泄漏显示在

行上
arrayDetPerformance = [[NSMutableArray alloc] initWithArray:arrayDetail];

另外,我对以下代码中保留计数从0直接变为2的原因感到困惑:

NSLog(@"Array2  : %d",[arrayDetail retainCount]);        //RETAIN COUNT IS 0
    arrayDetail = [[finalResult objectForKey:@"Detail"]
NSLog(@"Array2  : %d",[arrayDetail retainCount]);       //RETAIN COUNT IS 2

可能出现什么问题?

4 个答案:

答案 0 :(得分:2)

它显示泄漏,因为您分配arrayDetPerformance然后不释放它。就那么简单。至少这是我们从你向我们展示的代码中可以看出来的。

至于其余部分,请不要使用retainCount来调试内存问题!你必须理解简单的memory management rules并遵循它们,没有别的。由于您不知道Apple的底层代码的作用,因此您不能依赖于对象的保留计数。

关于此代码的问题:

NSLog(@"Array2  : %d",[arrayDetail retainCount]);        //RETAIN COUNT IS 0
arrayDetail = [[finalResult objectForKey:@"Detail"]
NSLog(@"Array2  : %d",[arrayDetail retainCount]);       //RETAIN COUNT IS 2

您要将整个其他对象分配给arrayDetail,因此在分配之前和之后比较arrayDetail的任何属性是完全没有意义的。保留计数可以遍布整个地方,也不会告诉你任何事情。

我觉得你真的不知道你在这做什么。您应该反复阅读内存管理规则,直到您彻底理解它们为止。

答案 1 :(得分:1)

retainCount无法帮助您调试问题(实际上它几乎从不与调试相关,所以最好忘记它甚至在那里)。< / p>

不要发布arrayDetail,因为您不拥有它。问题出在arrayDetPerformance上。您在该行上分配了一个对象,并且它没有在任何地方发布。现在,您可能在代码中的其他位置执行此操作,但如果您不是,请在使用完毕后发送release

修改

如果您要在arrayDetPerformance方法中取消分配dealloc,我假设它是一个实例变量?在这种情况下,您不能假设它没有指向某个对象,因此您应该在将其分配给新对象之前发送release

或者,如果它被配置为属性,只需使用self.arrayDetPerformance = ...,它将为您处理内存管理。

答案 2 :(得分:1)

不要调用retainCount

retainCount没用。对象的绝对保留计数是实现细节。规则很简单;如果您要保留某些内容,则必须在完成后将其释放。故事结束。

memory management documentation完全讨论了这一点。


首先,retainCount 永远不会返回零。如果您碰巧发送消息nil,那么您获得零的唯一时间。这样:

NSLog(@"Array2  : %d",[arrayDetail retainCount]);        //RETAIN COUNT IS 0
arrayDetail = [[finalResult objectForKey:@"Detail"]
NSLog(@"Array2  : %d",[arrayDetail retainCount]);       //RETAIN COUNT IS 2

您正在使arrayDetail指向该第二行上的其他对象。因此,该行之前/之后的保留计数之间没有关系。

当泄漏告诉你某个特定线路上有泄漏时......

arrayDetPerformance = [[NSMutableArray alloc] initWithArray:arrayDetail];

...它告诉你在该行上分配的所述对象被泄露了。 告诉您特定行是泄漏的原因。泄漏可能是因为您要么将其过度保留在其他地方或忘记泄漏它。

你在几条评论中说过,你“在你的dealloc中释放[某事]”。显示你的dealloc方法的实现。

答案 3 :(得分:-1)

[arrayDetPerformance release];没有写在你的代码中;

所以,它显示内存泄漏。