为什么我的自动释放对象不会被释放?

时间:2011-02-25 19:58:51

标签: cocoa macos memory-management autorelease

我正在调试一个奇怪的内存管理错误,我无法弄明白。我注意到我的一些物体在记忆中停留的时间比预期的要长。我检查了所有的内存管理,最后得出了一个非常不可能的结论,即我的autorelease个操作中的某些操作不会产生release。在什么情况下可能?我创建了一个小型测试Canary类,它在dealloc中记录消息,并且具有以下测试代码:

NSLog(@"On the main thread: %i.", [NSThread isMainThread]);
[[[Canary alloc] init] autorelease];

根据代码,我们确实在主线程上,但dealloc中的Canary直到很久才被调用。延迟不是确定性的,很容易花费数秒或更长时间。怎么可能?应用程序在Mac上运行,垃圾收集已关闭( Objective-C垃圾收集在目标上设置为 Unsupported 。)我主要习惯iOS,是OS X上的内存管理有多么重要?

3 个答案:

答案 0 :(得分:2)

autorelease没有按预期运行的唯一情况是当前线程上没有自动释放池。只有少数情况会发生这种情况,如果发生这种情况,您会在控制台上打印出非常响亮的日志消息。如果您没有看到该日志,则autorelease表现得恰当。更有可能的是,您的代码上的某些内容正在此Canary对象上调用retain,然后永远不会释放它。

答案 1 :(得分:2)

自动释放的对象在其池耗尽之前不会被释放。因此,如果您使用自动释放的缓冲区循环遍历图像,那么每次循环创建和排空池都会很好。

答案 2 :(得分:1)

Mike Ash的博客文章More Fun With Autorelease解释了这个问题的根源。引用:

  

每个人都知道,每次去   通过事件循环,Cocoa打击   离开旧游泳池并换上新游泳池   为了你,让你所有的   自动释放的物体消失了   新的进入一个新的游泳池。那   你永远不会建立更多的对象   而不是在一个单一的生产   事件循环周期。关键词是“事件循环”。在   苹果的无限智慧,事物   不是真正的实际NSEvents不   触发游泳池。

     

我正在开发一款应用程序   在后台花了很多时间   做着黑暗,难以形容的事情   NSStreams主线程。一世   我遇到了一个错误   对象可以在中被破坏   处理流事件的过程中,   这让其他人开放了   之后的流事件   释放。 (...)

     

显而易见的解决办法就是这样做   [[self retain] autorelease]之前   打电话问题。并解决它   做了,除了我的dealloc   发生在我的活动中间   处理程序,它从来没有发生过。

     

直到我点击了应用的停靠栏图标。

     

至少解决方案很简单。岗位   中的NSApplicationDefined事件   流事件处理程序,并自动释放   对象按计划销毁。

我发誓我必须从封面到封面阅读博客,这是投资的好时机。