One of the patterns presented at the WWDC 2010 \"Blocks and Grand Central Dispatch\" talk was to use nested dispatch_async calls to perform time consuming tasks on a backgro
You can use the __block
storage type qualifier for such a case. __block
variables are not automatically retained by the block. So you need to retain the object by yourself:
__block UIViewController *viewController = [myViewController retain];
dispatch_async(backgroundQueue, ^{
// Do long-running work here.
dispatch_async(dispatch_get_main_queue(), ^{
[viewController updateUIWithResults:results];
[viewController release]; // Ensure it's released on main thread
}
});
EDIT
With ARC, __block variable object is automatically retained by the block, but we can set nil value to the __block variable for releasing the retained object whenever we want.
__block UIViewController *viewController = myViewController;
dispatch_async(backgroundQueue, ^{
// Do long-running work here.
dispatch_async(dispatch_get_main_queue(), ^{
[viewController updateUIWithResults:results];
viewController = nil; // Ensure it's released on main thread
}
});
In a thread, I just use [viewController retain];
then at the end of the thread use
[viewController release]
. It works and I don't use GCD~
This worked for me (added a timer):
[self retain]; // this guarantees that the last release will be on the main threaad
dispatch_async(backgroundQueue, ^{
// do something time consuming in background
NSArray *results = ComputeBigKnarlyThingThatWouldBlockForAWhile();
// use results on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
[myViewController UpdateUiWithResults:results];
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(releaseMe:) userInfo:nil repeats:NO];
});
});
- (void)releaseMe:(NSTimer *)theTimer {
[self release]; // will be on the main thread
}