主队列上的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:
用普通的运行循环模式排队消息。 根据苹果公司的“ 并发编程指南” ,主队列将排队的任务与应用运行循环中的其他事件交织在一起。 因此,如果在事件队列中还有其他事件需要处理,则派遣队列中的排队块可以先运行,即使稍后提交。
这篇文章是一个非常好的解释,执行performSelectorOnMainThread
与dispatch_async
,它也回答了上述问题。
你用waitUntilDone=YES
尝试PerformSelectorOnMainThread
waitUntilDone=YES
例如:
码:
[viewController performSelectorOnMainThread:@selector(methodThatAddsSubview:) withObject:otherView waitUntilDone:YES];
我认为这可以解决为什么PerformSelectorOnMainThread
需要这么长时间来响应的问题。