问题
I was having problems modifying a view inside a thread. I tried to add a subview but it took around 6 or more seconds to display. I finally got it working, but I don\'t know how exactly. So I was wondering why it worked and what\'s 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 were called inside this Completetion Handler of the class of the ACAccountStore.
accountStore requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {
if(granted) {
//my methods were here
}
}
Edit: When I say it didn\'t work I meant it took about 6 seconds to display the view I added.
回答1:
By default, -performSelectorOnMainThread:withObject:waitUntilDone:
only schedules the selector to run in the default run loop mode. If the run loop is in another mode (e.g. the tracking mode), it won't run until the run loop switches back to the default mode. You can get around this with the variant -performSelectorOnMainThread:withObject:waitUntilDone:modes:
(by passing all the modes you want it to run in).
On the other hand, dispatch_async(dispatch_get_main_queue(), ^{ ... })
will run the block as soon as the main run loop returns control flow back to the event loop. It doesn't care about modes. So if you don't want to care about modes either, dispatch_async()
may be the better way to go.
回答2:
It's likely because performSelectorOnMainThread:withObject:waitUntilDone:
queues the message with common run loop modes. According to Apple's Concurrency Programming Guide, the main queue will interleave queued tasks with other events from the app's run loop. Thus, if there are other events to be processed in the event queue, the queued blocks in the dispatch queue may be run first, even though they were submitted later.
This article is a superb explanation to performSelectorOnMainThread
vs. dispatch_async
, which also answers the above question.
回答3:
Did you try thePerformSelectorOnMainThread
with waitUntilDone=YES
Eg:
Code:
[viewController performSelectorOnMainThread:@selector(methodThatAddsSubview:) withObject:otherView waitUntilDone:YES];
I think that might solve the issue as of why the PerformSelectorOnMainThread
takes so long to respond.
来源:https://stackoverflow.com/questions/9335434/whats-the-difference-between-performselectoronmainthread-and-dispatch-async-on