objective-c - 如何结束使用 detachNewThreadSelector 创建的轮询线程?

标签 objective-c ios multithreading nsthread

我正在使用 detachNewThreadSelector 创建一个新线程 ref使用 toTarget self.

该线程的目的是轮询运动并根据需要加载图像 - 它循环并仅在主线程中的原子 bool 设置为 true 时退出 - 这是在对象 dealloc 中设置的.

问题是这样引起的(来自detachNewThreadSelector引用):

The objects aTarget and anArgument are retained during the execution of the detached thread, then released

这意味着我的对象将始终具有(最小)保留计数 1 - 因为线程不断轮询。 dealloc 因此永远不会被调用。

所以我的问题是:如何在考虑到轮询线程的存在的情况下释放我的对象?

我现在唯一的想法是创建一个对象的 destroyThread 函数,它设置结束线程 bool 值,它会在我期望对象被销毁的任何地方调用。这看起来很容易出错,有没有更好的解决方案?

提前致谢。

更新

我有另一个解决方案的想法 - 在线程中我检测保留计数是否为 1 - 如果是 1 那么我知道线程正在使对象保持事件状态,所以我打破循环并调用 dealloc。这是一个可靠的解决方案吗?

最佳答案

首先,避免detachNewThreadSelector:。几乎可以肯定,使用调度队列或 NSOperationQueue 可以更好地完成您想用它做的任何事情。即使您需要手动创建线程(这在现代 ObjC 中极为罕见),最好创建显式 NSThread 对象并保留它们而不是使用 detachNewThreadSelector:这会创建一个您不能再直接与之交互的线程。

对于具体问题,如果您创建自己的线程,则需要将该 bool 值设置在 dealloc 以外的某个地方。这意味着程序的其他部分需要告诉您关闭。您不能仅通过这种方式使用手动线程释放并自动清理自己。


编辑:永远不要调用retainCount。涉及 retainCount 的解决方案都不是好的解决方案。抛开在更一般的情况下使用 retainCount 的各种实际问题,在这种情况下,它需要您手动进行引用计数。你应该尽快切换到 ARC,并且 retainCount 在 ARC 中是非法的(在 ARC 之前它应该是非法的,但他们终于有一个很好的借口来强制这个问题)。如果您不能在 ARC 中实现您的解决方案,那么它不太可能是一个好的解决方案。

同样,最好的解决方案是使用 GCD 调度队列(或操作,通常用调度队列实现)。与手动线程管理相比,它对几乎所有问题的效率和效果都令人难以置信。

如果您必须为遗留代码使用手动线程并且需要维护这种自动销毁,解决方案是拥有该线程的帮助对象。您的对象拥有 helper 对象,该对象与线程有一个保留循环。当您的对象被释放时,它会告诉线程关闭,这会打破保留循环,并且辅助对象会消失。这是管理保留循环的标准方法。

参见 Apple 的 Migrating Away From Threads了解更多。

关于objective-c - 如何结束使用 detachNewThreadSelector 创建的轮询线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11567396/

相关文章:

iOS 应用程序被拒绝 - 元数据被拒绝

ios - 如何从 iOS/iPhone 中的 Assets 库获取照片/视频源路径?

c - POSIX C 线程 - 将整数传递给线程函数

ruby-on-rails - 为什么 .with_lock 没有按我的预期工作?

python - 与手写 C 相比,pypy 是否可以快速处理线程和套接字?

objective-c - iOS : how to reduce size of large PNG files

objective-c - 如何将Unicode字符串(\u00e2等)转换成NSString显示?

objective-c - cocoa :以当前字体粘贴格式化文本?

iOS - 选择器 Controller 无法打开照片库

javascript - 每个版本的 iOS 附带什么版本的移动版 Safari?