首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用ARC,不为每个线程设置一个自动释放池是致命的吗?

使用ARC,不为每个线程设置一个自动释放池是致命的吗?
EN

Stack Overflow用户
提问于 2012-09-25 09:18:25
回答 2查看 9.3K关注 0票数 19

我读到了这个:

如果您在应用程序中创建了辅助线程,则需要为其提供自己的自动释放池。中进一步讨论了自动释放池及其包含的对象

在iOS 5开发人员食谱中。

我正在用ARC编译。我已经创建了许多后台线程,看起来我做得很好。我的后台线程都不是长时间运行的。比如说,所有这些对象都会被主线程的自动释放池释放吗?不然呢?

这就是我称之为后台线程的方式:

代码语言:javascript
复制
+(void)doBackground:(void (^)())block
{
    //DISPATCH_QUEUE_PRIORITY_HIGH
    //dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0), ^{
    dispatch_async(dispatch_get_global_queue(-2,0), ^{
        block();
    });
}

我是否应该将其更改为

代码语言:javascript
复制
+(void)doBackground:(void (^)())block
{
    //DISPATCH_QUEUE_PRIORITY_HIGH
    //dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0), ^{
    dispatch_async(dispatch_get_global_queue(-2,0), ^{
        @autoreleasepool{
        block();
        }
    });
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-09-25 12:17:26

如果你没有为你的新线程创建一个自动释放池,至少可以认为这是一个程序员的错误。这是否对你的程序是致命的取决于你的程序的实现。典型的问题是对象泄露,因此对象的dealloc永远不会执行(可能是致命的)。

在ARC下创建自动释放池的现代方法是:

代码语言:javascript
复制
void MONThreadsEntry() { // << entry is e.g. a function or method
  @autoreleasepool {
    ...do your work here...
  }
}

更详细地说,自动释放池的行为类似于线程本地堆栈--您可以推送和弹出,但在该线程上的任何内容被自动释放之前,应该始终存在一个本地堆栈。自动释放消息不会从一个线程传输到另一个线程。

如果您的“创建线程”的想法是使用更高级别的异步机制,例如使用NSOperationQueue,或者如果底层实现创建了一个辅助线程和它自己的自动释放池,那么您可能看不到问题(例如在控制台或泄漏中)。

无论如何,不要猜测何时创建自动释放池,只需了解您需要在哪里创建它们,以及何时应该创建它们。这一切都定义得很好--不需要猜测,也不需要害怕创建它们。

类似地,如果您使用的是较低级别的抽象,则永远不需要为线程创建自动释放池,也不需要在该线程上自动释放对象。例如,pthread和纯C实现不需要为自动释放池而烦恼(除非您使用的某些API假定它们已经存在)。

即使是Cocoa应用程序中的主线程也需要一个自动释放池--它通常不是您编写的东西,因为它存在于项目模板中。

更新--调度队列

回答更新的问题:是的,您仍然应该为在分派队列下运行的程序创建自动释放池--请注意,使用分派队列,您不会创建线程,因此这是一个与原始问题完全不同的问题。原因:尽管分派队列确实管理自动释放池,但no guarantee是关于清空它们的时间/点的。也就是说,您的对象将被释放(在某个时刻),但您还应该在此上下文中创建自动释放池,因为实现可能(理论上)每运行10,000个块就会耗尽池,或者大约每天。因此,在这种情况下,只有当您最终消耗太多内存时,或者当您的程序期望它的对象将以某种确定的方式销毁时,它才是致命的--例如,您可能正在后台加载或处理图像,如果这些图像的寿命因自动释放池而意外延长,则最终会消耗大量内存。另一个例子是共享资源或全局对象,您可以响应通知或引入竞争条件,因为您的“块本地”对象可能比您预期的更长。还要记住,实现/频率可以根据其实现者的需要自由更改。

票数 35
EN

Stack Overflow用户

发布于 2012-09-25 09:44:46

现在似乎自动释放池是自动为新线程创建的。我不知道这是什么时候改变的,也不知道为什么文档中有相反的说法,但仅此而已。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12575010

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档