iOS 过早释放对象 - 可能与 Autorelease 和 Copy 混淆
Posted
技术标签:
【中文标题】iOS 过早释放对象 - 可能与 Autorelease 和 Copy 混淆【英文标题】:iOS Releasing object too early - possible confusion with Autorelease and Copy 【发布时间】:2011-09-01 08:00:25 【问题描述】:我编写了一个包含自定义搜索类的应用程序。这会构建一个结果数组。
然后我将该数组分配给我的 FirstViewController 类,并重新加载一个表格视图,其中分配了结果数组
self.aResults = [thisSearch.aResults copy]
...
[[self searchResults] reloadData];
在此之后不久,我将发布 thisSearch
[thisSearch release];
这一切都很好,并显示了结果表,但是如果我向下滚动表格并查看下面的行它们都是空白的,那么当我向上滚动应用程序时,它会在重新加载回收的表格单元格时崩溃。
这在我之前没有发生过,但我意识到我正在泄漏内存,所以我发疯了 autorelease,并在我的 中添加了很多 autorelease搜索 类。但不是我的 FirstViewController 类。
所以如果我使用Copy,它实际上并没有复制对象,它只是增加了引用计数器吗?因此,当我销毁 Search 时,我是否会销毁其中的结果数组,从而销毁 FirstViewController 试图访问表视图的内容?
对不起,如果这没有多大意义,我今天不太适应。
【问题讨论】:
您应该创建一个像@property (nonatomic, copy) NSArray *aResults;
这样的Results 复制属性,而不是self.aResults = [thisSearch.aResults copy]
。然后,当您设置此属性时,它将自动获取您设置的对象的副本。处理完 aResults 中的任何内容后,执行self.aResults = nil
,它将被释放。我没有将此作为答案提交,因为它只是一个提示,但这不是您的应用程序崩溃的原因。而且没有更多代码,我不知道为什么会这样。
【参考方案1】:
当您 copy
对象时(并且要这样做,该对象必须符合 NSCopying
协议,但 NSArray
就是这种情况),就像您第一次使用 init
ializing 它一样预定义值。
因此,您对 release
的对象负责,这些对象已成为 copied
。
你必须这样做:
self.aResults = [thisSearch.aResults copy]
...
[thisSearch release]; // When you release thisSearch this will not affect aResults
...
// then you can either do:
[self.aResults autorelease]; // but then do not release it later on
// or
[self.aResults release]; // when you're done with it
但是我怀疑这会解决你的记忆问题。通过过度自动释放(并且仍然释放东西),您可能已经完全破坏了您的应用程序内存管理。
要尝试修复它,请尝试分析您的项目,看看会发生什么。
我还附上了Apple Memory Management link,人们应该每月阅读它,直到它成为第二天性。
【讨论】:
啊啊我应该运行分析!我运行了它,它指向一个我正在自动释放的 NSDicitonary,并告诉我引用计数器已经为 0,因为我将该字典分配给一个也是自动释放的数组 - 所以我想它试图释放那个字典当它所在的数组已经消失时以上是关于iOS 过早释放对象 - 可能与 Autorelease 和 Copy 混淆的主要内容,如果未能解决你的问题,请参考以下文章