2

我有一些代码,类似于下面的代码:EXC_BAD_ACCESS嵌套dispatch_async与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财产。

我得到了来自用户的崩溃报告试图将doSomethingExpensiveWithObject:通话中访问的innerObject物业时,显示的EXC_BAD_ACCESSobjc_msgSend()

起初我想,也许是autoreleasePool被抽干所以innerObject例如从doSomethingExpensiveWithObject:返回之前公布,但据我所知anObject应该由内dispatch_async呼叫也应保持innerObject活着被保留。

我错过了什么?

+1

代码的工作没有队列?此外,你[不需要分配一个NSAutoreleasePool](http://stackoverflow.com/questions/4141123/do-you-need-to-create-an-nsautoreleasepool-within-a-block-in-gcd)这里。 – DarkDust

+0

块不影响它们捕获的对象的保留数。 – user1139069

+0

@DarkDust这段代码被称为主线程。代码击中文件系统并执行Web请求,所以我在后台执行并逐渐更新UI。我添加了'NSAutoreleasePool',因为在昂贵的操作中分配了许多对象。 –

回答

1

仪器将迅速完成此工作 - 使用僵尸运行并在停止时查看引用计数。

+1

我无法重现该错误,因此运行僵尸工具现在无法帮助。 –