嵌套dispatch_async中的EXC_BAD_ACCESS与NSAutoreleasePool

时间:2012-01-20 17:35:32

标签: objective-c exc-bad-access grand-central-dispatch nsautoreleasepool

我有一些类似于以下代码的代码:

dispatch_queue_t queue          = dispatch_queue_create("", 0);
dispatch_queue_t inner_queue    = dispatch_queue_create("", 0);
dispatch_async(queue,
^{
    NSAutoreleasePool* autoreleasePool = [[NSAutoreleasePool alloc] init];
    NSArray* objects = [self.otherObject getObjectsFromSlowQuery];

    [objects enumerateObjectsWithUsingBlock:^(id anObject, NSUInteger idx, BOOL *stop) 
    {
        [anObject prepare];
        dispatch_async(inner_queue,
        ^{
            InnerObject* innerObject = anObject.innerObject;
            [self.helper doSomethingExpensiveWithObject:innerObject];
        });
        dispatch_sync(self.syncQueue,
        ^{
             [self insertIntoCollection:anObject];
        });
    }];
    dispatch_release(inner_queue);
    [autoreleasePool drain];
});
dispatch_release(queue);

[anObject.innerObject]属于nonatomic属性。

我收到了用户的崩溃报告,该报告在objc_msgSend()调用中尝试访问innerObject的媒体资源时,在doSomethingExpensiveWithObject:中显示 EXC_BAD_ACCESS 。< / p>

起初我在考虑可能autoreleasePool已耗尽,因此innerObject实例在从doSomethingExpensiveWithObject:返回之前已被释放但据我所知anObject应该保留通过内部dispatch_async调用,这也应该使innerObject保持活跃状态​​。

我错过了什么?

1 个答案:

答案 0 :(得分:1)

乐器可以快速完成这项工作 - 与僵尸一起运行并在停止时查看引用计数。