我正在调试一个奇怪的内存管理错误,我无法弄明白。我注意到我的一些物体在记忆中停留的时间比预期的要长。我检查了所有的内存管理,最后得出了一个非常不可能的结论,即我的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上的内存管理有多么重要?
答案 0 :(得分:2)
autorelease
没有按预期运行的唯一情况是当前线程上没有自动释放池。只有少数情况会发生这种情况,如果发生这种情况,您会在控制台上打印出非常响亮的日志消息。如果您没有看到该日志,则autorelease
表现得恰当。更有可能的是,您的代码上的某些内容正在此Canary对象上调用retain
,然后永远不会释放它。
答案 1 :(得分:2)
自动释放的对象在其池耗尽之前不会被释放。因此,如果您使用自动释放的缓冲区循环遍历图像,那么每次循环创建和排空池都会很好。
答案 2 :(得分:1)
Mike Ash的博客文章More Fun With Autorelease解释了这个问题的根源。引用:
每个人都知道,每次去 通过事件循环,Cocoa打击 离开旧游泳池并换上新游泳池 为了你,让你所有的 自动释放的物体消失了 新的进入一个新的游泳池。那 你永远不会建立更多的对象 而不是在一个单一的生产 事件循环周期。关键词是“事件循环”。在 苹果的无限智慧,事物 不是真正的实际NSEvents不 触发游泳池。
我正在开发一款应用程序 在后台花了很多时间 做着黑暗,难以形容的事情 NSStreams主线程。一世 我遇到了一个错误 对象可以在中被破坏 处理流事件的过程中, 这让其他人开放了 之后的流事件 释放。 (...)
显而易见的解决办法就是这样做
[[self retain] autorelease]
之前 打电话问题。并解决它 做了,除了我的dealloc 发生在我的活动中间 处理程序,它从来没有发生过。直到我点击了应用的停靠栏图标。
至少解决方案很简单。岗位 中的
NSApplicationDefined
事件 流事件处理程序,并自动释放 对象按计划销毁。
我发誓我必须从封面到封面阅读博客,这是投资的好时机。