您使用
的原因是什么?[self performSelectorOnMainThread:@selector(example:) withObject:nil waitUntilDone:YES];
更简单
[self example];
呼叫。
似乎他们都做同样的事情。我只看到performSelectorOnMainThread
似乎在xcode中调试起来比较困难,但其他方面没有区别。
答案 0 :(得分:1)
如果当前线程是主线程,那么你是对的,它将直接调用选择器。
但显然,在主线程上没有理由调用performSelectorOnMainThread:
(除非你不确定当前线程是否为主线程)。
调用此方法将确保选择器将在主线程上执行,而在另一个线程上执行,这可能因各种原因非常重要。 一个例子是与UI相关的所有内容,因为这些东西通常不应该在辅助线程上完成。
想象一下:
dispatch_async
(
dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 )
^( void )
{
/* Do heavy work, not blocking the main thread */
[ myView setBackgroundColor: [ UIColor redColor ] ];
}
);
以下代码通常被认为是危险的,因为您正在从辅助线程访问UI属性。通常只能从主线程访问UI属性。
这就是您使用performSelectorOnMainThread:
:
dispatch_async
(
dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 )
^( void )
{
/* Do heavy work, not blocking the main thread */
[ myView performSelectorOnMainThread: @selector( setBackgroundColor: ) withObject: [ UIColor redColor ] waitUntilDone: YES ];
}
);
修改强>
您可能会认为,因为您为YES
参数传递了waitUntilDone:
,所以它应该与直接调用选择器相同。
但不是。问题是被调用的选择器可能没有被同步,以便从不同的线程工作。
考虑设置属性,如上例所示。如果属性为nonatomic
,则可能会出现问题,即使您自己的线程“等待”直到执行选择器,因为这不会阻止与其他线程(包括主线程)的竞争条件。
编辑2
顺便说一下,当从不同的线程访问属性时,将它们声明为atomic
显然比每次需要访问它时使用performSelectorOnMainThread:
更好。
同时考虑dispatch_sync
或dispatch_async
,将dispatch_get_main_queue
作为第一个参数传递,因为它通常是重新加入主线程的更好方法。
答案 1 :(得分:1)
也可以将评论作为答案发布。
从主线程调用performSelectOnMainThread:withObject:waitUntilDone:
并将YES
传递给waitUntilDone:
参数与直接调用选择器相同。换句话说,它毫无意义。
传递NO
会产生很大的影响。选择器排队等候,稍后会运行。
当然,如果当前线程不是主线程,那么会有很大的不同。
实际上我可以想到在主线程中使用performSelectOnMainThread:withObject:waitUntilDone:
和YES
的一个原因 - 可能从任何线程调用的代码,包括主线程。