What is the difference between performSelectorOnMainThread and dispatch_async in the main queue?

I am having trouble changing the view inside the stream. I tried to add a subview, but it took about 6 seconds to display. I finally got his job, but I don’t know how. So I was wondering why this worked and what is the difference between the following methods:

//this worked -added the view instantly dispatch_async(dispatch_get_main_queue(), ^{ //some UI methods ej [view addSubview: otherView]; } //this took around 6 or more seconds to display [viewController performSelectorOnMainThread:@selector(methodThatAddsSubview:) withObject:otherView waitUntilDone:NO]; //Also didnt work: NSNotification methods - took also around 6 seconds to display //the observer was in the viewController I wanted to modify //paired to a method to add a subview. [[NSNotificationCenter defaultCenter] postNotificationName: @"notification-identifier" object:object]; 

For reference, this was called inside this Completetion handler of the ACAccountStore class.

 accountStore requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) { if(granted) { //my methods were here } } 

Edit: When I say that this did not work, I intended that it took about 6 seconds to display the view I added.

+51
multithreading ios objective-c uikit grand-central-dispatch
Feb 17 '12 at 21:10
source share
3 answers

By default, -performSelectorOnMainThread:withObject:waitUntilDone: only assigns a selector to run in the default run loop mode. If the run cycle is in a different mode (for example, tracking mode), it will not work until the run cycle returns to the default mode. You can get around this with the -performSelectorOnMainThread:withObject:waitUntilDone:modes: (by passing all the modes you want to run it to).

On the other hand, dispatch_async(dispatch_get_main_queue(), ^{ ... }) will start the block as soon as the main run loop returns the control flow back to the event loop. He does not care about the modes. Therefore, if you don't want to care about modes, dispatch_async() might be the best way.

+68
Feb 17 '12 at 22:20
source share

Probably because performSelectorOnMainThread:withObject:waitUntilDone: queues a message with common run loop modes. According to the Apple Concurrency Programming Guide , the main queue will alternate tasks with the queue with other events from the application launch cycle. Thus, if there are other events in the event queue, the queues in the send queue can be started first even if they were sent later.

This article is an excellent explanation of performSelectorOnMainThread vs. dispatch_async , which also answers the above question.

+1
Aug 18 '16 at 14:05
source share

Have you tried PerformSelectorOnMainThread with waitUntilDone=YES

For example:

The code:

 [viewController performSelectorOnMainThread:@selector(methodThatAddsSubview:) withObject:otherView waitUntilDone:YES]; 

I think this may solve the question of why PerformSelectorOnMainThread has been reacting for so long.

0
Jun 25 '14 at 13:26
source share



All Articles