主队列上的performSelectorOnMainThread和dispatch_async有什么区别?

我在修改线程内的视图时遇到问题。 我试图添加一个子视图,但需要大约6秒或更长时间来显示。 我终于搞定了,但我不知道如何。 所以我想知道为什么它的工作和以下方法有什么区别:

//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]; 

为了参考,在ACAccountStore的这个类的Completetion处理程序中调用了这个参数。

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

编辑:当我说它没有工作,我的意思是花了大约6秒钟来显示我添加的视图。

默认情况下, -performSelectorOnMainThread:withObject:waitUntilDone:仅调度select器以默认运行循环模式运行。 如果运行循环处于另一种模式(例如跟踪模式),它将不会运行,直到运行循环切换回默认模式。 你可以通过variables-performSelectorOnMainThread:withObject:waitUntilDone:modes: (通过传递你希望它运行的所有模式)来解决这个问题。

另一方面,一旦主运行循环将控制stream返回到事件循环, dispatch_async(dispatch_get_main_queue(), ^{ ... })将运行该块。 它不关心模式。 所以如果你不想关心模式, dispatch_async()可能是更好的方法。

这很可能是因为performSelectorOnMainThread:withObject:waitUntilDone:用普通的运行循环模式排队消息。 根据苹果公司的“ 并发编程指南” ,主队列将排队的任务与应用运行循环中的其他事件交织在一起。 因此,如果在事件队列中还有其他事件需要处理,则派遣队列中的排队块可以先运行,即使稍后提交。

这篇文章是一个非常好的解释,执行performSelectorOnMainThreaddispatch_async ,它也回答了上述问题。

你用waitUntilDone=YES尝试PerformSelectorOnMainThread waitUntilDone=YES

例如:

码:

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

我认为这可以解决为什么PerformSelectorOnMainThread需要这么长时间来响应的问题。