【问题标题】:Memory Leak: Issues with releasing NSArray in iPhone app内存泄漏:在 iPhone 应用程序中发布 NSArray 的问题
【发布时间】:2011-04-15 10:37:11
【问题描述】:

我有一个显示 Instruments 泄漏的代码。它显示了我用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 是如何声明的?它是财产吗?
  • 旁注:AFAIK 你不应该在运行时依赖 [yourObj retainCount] 值...保留计数只能在 Instruments 中有用。
  • @Nick Weaver:是的,它是一个具有属性(非原子,保留)的 NSMutableArray,并且是合成的。有什么问题?
  • 您是在设置arrayDetPerformance,就像在您的代码中显示的那样,还是实际上在使用self.arrayDetPerformance = ...
  • -retainCount 可以永远不会返回零

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


【解决方案1】:

它显示了泄漏,因为您分配了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 的任何属性是完全没有意义的。保留计数可能无处不在,它不会告诉您任何信息。

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

【讨论】:

  • @PARTH:所以也许当 dealloc 被调用并试图在你使用它之前释放 arrayDetPerformance,所以它从未被初始化/分配?
【解决方案2】:

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

不要发布arrayDetail,因为你不拥有它。问题在于arrayDetPerformance。您正在该行上分配一个对象,并且它不会在任何地方释放。现在,您可能会在代码的其他地方这样做,但如果不是,请在使用完毕后发送release

编辑

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

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

【讨论】:

  • 我已经在我的 dealloc 方法中释放了我的 arrayDetPerformance 那么还有什么问题呢?
【解决方案3】:

不要调用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];

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

你在几个 cmets 中说过你正在“在你的 dealloc 中释放 [something]”。显示你的 dealloc 方法的实现。

【讨论】:

  • 我几乎要搜索你的另一个答案来剪切和粘贴第一段! :)
【解决方案4】:

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

所以,它的显示内存泄漏。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-12
    • 1970-01-01
    相关资源
    最近更新 更多