主队列上的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类的完成处理程序内部调用了该方法。


accountStore requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {

            if(granted) {

            //my methods were here

            }

}

编辑:当我说它不起作用时,我的意思是花了大约6秒钟才能显示我添加的视图。


白衣非少年
浏览 945回答 3
3回答

RISEBY

默认情况下,-performSelectorOnMainThread:withObject:waitUntilDone:仅计划选择器以默认运行循环模式运行。如果运行循环处于另一种模式(例如跟踪模式),则在运行循环切换回默认模式之前它不会运行。您可以使用该变体来解决此问题-performSelectorOnMainThread:withObject:waitUntilDone:modes:(通过传递您希望它在其中运行的所有模式)。另一方面,dispatch_async(dispatch_get_main_queue(), ^{ ... })一旦主运行循环将控制流返回到事件循环,就会运行该块。它不在乎模式。因此,如果您也不想关心任何模式,dispatch_async()可能是更好的选择。

小唯快跑啊

可能是因为performSelectorOnMainThread:withObject:waitUntilDone:使用常见的运行循环模式将消息排队。根据Apple的《并发编程指南》,主队列将把排队的任务与应用程序运行循环中的其他事件进行交错。因此,如果事件队列中还有其他事件要处理,则调度队列中的已排队块可以先运行,即使它们是稍后提交的。本文是performSelectorOnMainThreadvs. 的出色解释dispatch_async,它也回答了上述问题。

泛舟湖上清波郎朗

你试试PerformSelectorOnMainThread用waitUntilDone=YES例如:码:[viewController performSelectorOnMainThread:@selector(methodThatAddsSubview:) withObject:otherView waitUntilDone:YES];我认为这可能会解决问题,因为为什么PerformSelectorOnMainThread需要这么长时间才能做出回应。
打开App,查看更多内容
随时随地看视频慕课网APP