【问题标题】:Using NSAutoReleasePool in an NSOperation on Secondary Thread in start and finish methods): Crashes在开始和结束方法的辅助线程上的 NSOperation 中使用 NSAutoReleasePool):崩溃
【发布时间】:2012-03-17 13:59:23
【问题描述】:

我有一个 NSOperation,我想用 NSAutoreleasePool 括起来,如下所示:

- (void) start {

    opPool = [[NSAutoreleasePool alloc] init];

    if (self.isCancelled) {
        [self finish];
    }
    ''' more code ...   
}

- (void) finish {

    [opPool release];

    [[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:nil];
    ... more finish code here ...
    self.state = LSOperationStateFinished;
}

opPool 是一个 iVar。

该操作在没有 NSAutoreleasePool 分配和释放的情况下工作。但它会崩溃,如图所示实现。

我在这两个方法中都放了一个断点,看看 [NSThread currentThread] 的描述是什么。两种方法里面都是一样的。

我对 Autorelease Pools 文档的理解是,我应该为与主线程分开的后台线程设置一个。这就是我想要的方式,但显然这不是正确的方式?

我在做一些根本错误的事情吗?我应该怎么做才能满足书面要求?

【问题讨论】:

    标签: objective-c memory-leaks nsoperation nsautoreleasepool


    【解决方案1】:

    如果发生崩溃,请发布回溯。

    事实上,没有足够的信息来说明任何具体的事情。

    在任何情况下,您都可能过度发布某些内容。打开僵尸,看看是否有帮助。

    【讨论】:

    • 那么你能确认我没有对我展示的代码做一些根本性的错误吗?如果不是,那么我想我可能错误地释放了一个自动释放的对象。我在调试器或仪器中没有看到任何僵尸。它只是在 NSOperation 的辅助线程中崩溃..
    • 我应该补充一点,它在发布时就崩溃了。我可以在那里运行到一个断点,它在第一步就崩溃了。
    【解决方案2】:

    你可以将自己的NSAutoreleasePool插入主线程,没关系。

    HERE 是一个关于它的线程。

    我认为导致您崩溃的主要原因是[opPool release];。你试过[opPool drain];而不是[opPool release];吗?


    编辑:

    您似乎将您的opPool 声明为iVar,那么您是否在dealloc 中发布了它?如果是这样,你得到了两个release,结果崩溃了。

    也许您可以尝试以下方法:

    ...
    NSAutoreleasePool * opPool = [[NSAutoreleasePool alloc] init];
    
    [self start];
    [self finish];
    
    [opPool drain];
    ...
    

    【讨论】:

    • 唯一的版本是finish方法。但到那时它应该释放池拥有的所有对象,所以我猜池中的某些东西被过度释放了。我不知道在主线程中初始化和耗尽/释放池是否可以。这就是为什么我在开始和结束时都有它。 dealloc 在主线程中运行。
    • @Jim Ya,它可能被过度发布了。 “我不知道在主线程中初始化和耗尽/释放池是否可以”就像我说的那样,你可以看到我在帖子中粘贴的线程,他们讨论过它。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-13
    相关资源
    最近更新 更多