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

我無法重現該錯誤,因此運行殭屍工具現在無法幫助。 –