Objective-C多线程,当一个对象在其方法被执行时被释放会发生啥? (以及如何预防?)
Posted
技术标签:
【中文标题】Objective-C多线程,当一个对象在其方法被执行时被释放会发生啥? (以及如何预防?)【英文标题】:Objective-C multithreading, what happens when an object gets dealloc while its methods are being executed? (And how to prevent it?)Objective-C多线程,当一个对象在其方法被执行时被释放会发生什么? (以及如何预防?) 【发布时间】:2011-01-25 17:37:29 【问题描述】:我正在为 iPhone 编写一个应用程序并遇到这种情况。
我有一个视图控制器 myViewController,只要用户点击屏幕上的“返回”按钮,它就会解除分配。后台有一个线程与远程服务器通信,并可能向 myViewController 中的方法、updateUI、方法发送消息。
如果后台线程在 myViewController 中发送 updateUI 消息,但用户恰好在正确的时间点按了“返回”按钮,导致 myViewController 在 updateUI 仍在执行时解除分配,会发生什么情况?
我的猜测是如果 updateUI 最终使用空指针,dealloc 方法将运行并且应用程序可能会崩溃。假设是这种情况,我目前的解决方案是:
[self retain];
// updateUI code here
[self release];
我不确定这是否是最好的解决方案,因为我觉得这是处理多线程时的常见问题。
我的假设正确吗?如果有,有没有更好的解决方案?
【问题讨论】:
【参考方案1】:您所描述的内容称为“竞争条件”。竞态条件在测试中很难识别,一旦报告就很难追踪并重现,因为有时在调试器中执行可以有效地修改代码的执行方式(避免尝试重现的情况)。竞争条件是并发编程中的主要缺陷之一 - 使该领域看似难以做好。
原则上,最佳做法是尽量减少共享资源的使用,并严格限定在实现并发时如何协调共享。如果一个对象在多个线程之间共享,则每个线程都应该保留它,以确保在每个线程完成其处理时该对象保持在范围内。
Apple 一直在采取措施简化并发实施。这是熟悉 ios 主题的一个很好的起点。 http://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/Introduction/Introduction.html%23//apple_ref/doc/uid/TP40008091
注意 Objective-C 2.0 的属性可以支持原子操作(默认情况下是原子的,因此使用 nonatomic 关键字禁用此默认值)也很有用。 http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocProperties.html
而且,这是线程的老派指南(不受欢迎的方法,但仍然有用的背景 - 一定要熟悉 NSLock)。 http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/Introduction/Introduction.html%23//apple_ref/doc/uid/10000057i
【讨论】:
【参考方案2】:当您的代码的某些部分依赖于另一个部分时,它应该保留这种依赖关系,直到不需要它为止。在您的情况下,后台工作人员应保留控制器,并仅在工作完成(或取消)时释放它。
【讨论】:
不要忘记充分考虑您的各种数据结构如何确保并发读/写的完整性......哦,顺便说一句,多线程很难。 :)。【参考方案3】:如果您 dealloc
然后 nil 您的对象,那么这应该不是问题 - 您可以在 Objective-c 中向 nil
发送消息。
或者,如果您希望 viewController 获取消息并且您的目标是 iOs 4,您可以使用块和 GCD。块会自动保留对象,因此如果一个块引用了您的 viewController,即使 -(void)dealloc ;
已被调用,它也会根据需要保留它。
Here 是一个不错的 Block 教程
【讨论】:
【参考方案4】:是的,您的应用会崩溃,可能与 EXC_BAD_ACCESS
类似。
就多线程而言,您将希望保留您的对象,直到对它们进行所有操作 并进行防御性编程。在尝试操作对象之前检查对象是否存在。
【讨论】:
以上是关于Objective-C多线程,当一个对象在其方法被执行时被释放会发生啥? (以及如何预防?)的主要内容,如果未能解决你的问题,请参考以下文章
《Objective-C高级编程 iOS与OS X多线程和内存管理》读书笔记