EXC_BAD_ACCESS во вложенном dispatch_async с NSAutoreleasePool - PullRequest
2 голосов
/ 20 января 2012

У меня есть некоторый код, который похож на следующий код:

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.

Я получил отчет о сбое от пользователя, которыйпоказывает EXC_BAD_ACCESS в objc_msgSend() при попытке доступа к свойству innerObject в вызове doSomethingExpensiveWithObject:.

Сначала я подумал, что, возможно, autoreleasePool был истощен такэкземпляр innerObject был освобожден до возвращения из doSomethingExpensiveWithObject:, но, насколько я знаю, anObject должен быть сохранен внутренним вызовом dispatch_async, который также должен поддерживать innerObject в живых.

Чего мне не хватает?

1 Ответ

1 голос
/ 20 января 2012

Инструменты сделают это быстро - бегите с зомби и просматривайте счетчик ссылок, когда он остановится.

...