目标C语言 内存泄漏:在iPhone应用程序中释放NSArray的问题



我有一个代码,显示仪器泄漏。它显示了我用arrayDetail

的内容初始化arrayDetPerformance的泄漏

如果我释放我的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

怎么了?

显示泄漏,因为您分配了arrayDetPerformance,然后没有释放它。就是这么简单。至少我们可以从你给我们看的代码中看出这一点。

至于其余的,永远不要使用retainCount来调试内存问题!您必须了解简单的内存管理规则并遵循这些规则,仅此而已。因为你不知道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的任何属性是完全没有意义的。保留计数可能到处都是,它不会告诉你任何事情。

我的印象是你并不知道你在这里做什么。您应该一遍又一遍地阅读内存管理规则,直到完全理解它们为止。

retainCount不会帮助你调试你的问题(事实上,它几乎永远不会与调试相关,所以最好忘记它的存在)

不要发布arrayDetail,因为你不拥有它。问题在于arrayDetPerformance。你在这条线上分配了一个对象,它没有被释放到任何地方。现在,你可能在代码的其他地方这样做,但如果你没有,当你用完它时,给它发送一个release

编辑

如果你在dealloc方法中释放arrayDetPerformance,我假设它是一个实例变量?在这种情况下,你不能假设它没有指向一个对象,所以你应该在把它赋值给新对象之前给它发送一个release

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

不要调用retainCount

retainCount没用。对象的绝对保留计数是一个实现细节。规则很简单;如果你让某样东西被保留,你必须让它在你用完之后被释放。故事到此结束

内存管理文档详细讨论了这个问题。


首先,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在第二行指向不同的对象。因此,该行前后的保留计数之间没有关系。

当leaks告诉你某一行出现了泄漏,就像这样…

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

…它告诉您在该行上分配的所述对象被泄露了。它是而不是告诉您特定的行是导致泄漏的原因。泄漏很可能是因为您在其他地方过多地保留了它,或者忘记泄漏它。

您在几个评论中说您正在"dealloc中释放[某些东西]"。显示dealloc方法的实现

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

显示内存泄漏

最新更新