Consider this setup:
Object A creates object B for doing some work, and sets itself as B’s delegate to be informed of work progress.
B does some work with GCD blocks, and signals back to A with the delegate method about work completion. A wants to tear down (release) B upon work completion.
In code terms:
Object A:
B *b = [[B alloc] init];
b.delegate = self;
[b doSomeWork];
- (void) didSomeWorkFromB:(B *)b {
[b release];
b = nil;
}
Object B:
- (void) doSomeWork {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
doSomeWork();
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Work is complete.");
[self.delegate didSomeWorkFromB:self];
});
});
}
PROBLEM: calling [b release] inside object A causes a crash. I think it’s because the dispatch queue/background code is still running when A tries to release B.
QUESTION: how do I properly set up the objects and signaling in this case, to make sure that A only destroys B when all the background work has been completed?
Bogus question. It actually works as expected and the code above does not crash. The crash was caused by some unrelated code.