comparison GCD vs. performSelectorInBackground: dispatch_async not in background
UIKit classes should be used only from an application’s main thread. (From iOS4, drawing to a graphics context is thread-safe.) You can't use UIKit stuff in a background thread.
Thus, you can only use dispatch_async(dispatch_get_main_queue(), block) in this situation.
dispatch_async(dispatch_get_main_queue(), ^(void) {
It will invoke the block on the main thread in the runloop of the main thread.
dispatch_async(dispatch_queue_create("myGCDqueue", NULL), ^(void) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
It will invoke the block in a background thread. You can't use it because you want to use UIKit in the block. And be careful dispatch_async(dispatch_queue_create(, it might cause memory leak, you have to release the serial queue that is created by dispatch_queue_create.
dispatch_sync(dispatch_queue_create("myGCDqueue", NULL), ^(void) {
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
dispatch_sync waits until the block is done.
dispatch_sync(dispatch_get_main_queue(), ^(void) {
It causes DEADLOCK.
Admin
Updated on June 05, 2022Comments
-
Admin almost 2 years
Grand Central Dispatch is great and reduces the amount of code but why I cannot run something on a background thread?
I have made a sample application to show what I mean (none of the commented work):- (IBAction)performSel { [self performSelectorInBackground:@selector(doStuff) withObject:nil]; [NSThread sleepForTimeInterval:3]; [[self.view.subviews lastObject] removeFromSuperview]; } - (IBAction)gcd { dispatch_async(dispatch_queue_create("myGCDqueue", NULL), ^(void) { //dispatch_sync(dispatch_queue_create("myGCDqueue", NULL), ^(void) { //dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { //dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { //dispatch_async(dispatch_get_main_queue(), ^(void) { //dispatch_sync(dispatch_get_main_queue(), ^(void) { [self doStuff]; // only for readability, will move the code on success }); [NSThread sleepForTimeInterval:3]; [[self.view.subviews lastObject] removeFromSuperview]; } - (void)doStuff { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; UIView *abortingView = [[UIView alloc]initWithFrame: self.view.bounds]; abortingView.backgroundColor = [UIColor whiteColor]; abortingView.alpha = 0.7; [self.view insertSubview:abortingView atIndex:10]; [abortingView release]; [pool drain]; }
the
[NSThread sleepForTimeInterval:3];
is to simulate a default UI functionality. For example if someone is switching from one navigation view to another.
Simply copy the code in a new view based application, create two buttons and connect them. -
shw almost 12 yearsyou shouldn't use
dispatch_queue_create("myGCDqueue", NULL)
like that because you'd be leaking. you have to release queue you created at some point - usually after dispatching some block onto it