Objective c 在obj-c中调用主线程的这两种方法有什么不同吗?

Objective c 在obj-c中调用主线程的这两种方法有什么不同吗?,objective-c,multithreading,Objective C,Multithreading,下面是使用block调用的代码: dispatch_async(dispatch_get_main_queue(), ^{ [self doSomething]; }); 这一个正在使用选择器调用: [self performSelectorOnMainThread:@selector(doSomething) withObject:nil waitUtilDone:NO]; 是-在第一种情况下,创建一个块并将其发布到主队列调度\u异步将复制块。复制块会使其保留所引用的每个对象。因此

下面是使用
block
调用的代码:

dispatch_async(dispatch_get_main_queue(), ^{
   [self doSomething];
});
这一个正在使用选择器调用:

[self performSelectorOnMainThread:@selector(doSomething)
 withObject:nil
waitUtilDone:NO];

是-在第一种情况下,创建一个块并将其发布到主队列<代码>调度\u异步将
复制
块。复制块会使其保留所引用的每个对象。因此,
self
将被保留,就像您在块中提到的任何其他对象一样。控制区块的机制是中央大调度

在第二种情况下,只需在主线程上调度对
doSomething
的调用。进行调用的机制将是一个运行循环
self
,最多保留一个参数对象

GCD和运行循环之间的区别在于运行循环具有模式。只有当运行循环处于兼容模式时,才能将要执行的事情排队。在实践中,您最常用的方法是将要在
NSDefaultRunLoopMode
中发生的事情排队。当用户与用户界面交互时,它会切换到默认模式以外的模式。因此,在用户停止交互之前,您的工作不会发生。例如,在iOS上,用户被视为在手指向下时进行交互。因此,您可以安排一些您知道过于繁重的工作,比如说,平滑滚动无法继续,以便在用户完成交互后立即发生


您指定的选择器将使用
NSRunLoopCommonModes
,其中包括跟踪(用户交互)模式,但与
performSelectorOnMainThread:…模式:

进行比较和对比,您确定吗?我非常确定
performselectorinmainhread:…
确实保留了接收器和参数。@Chuck我在文档中找不到确切的答案,但简单的测试表明您是对的,因此很有可能会通过
nsrunlop
-performSelector:target:argument:order:modes: