I have some code which is similar to the following code:
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);
Where [anObject.innerObject] is a nonatomic property.
I got a crash report from a user which shows an EXC_BAD_ACCESS in objc_msgSend() when trying to access a property of innerObject within the doSomethingExpensiveWithObject: call.
At first I was thinking that perhaps the autoreleasePool was drained so the innerObject instance was released before returning from doSomethingExpensiveWithObject: but as far as I know anObject should be retained by the inner dispatch_async call which should also keep the innerObject alive.
What am I missing?