iOS是由在主线程上执行的委托和观察者调用的方法



对不起,我不确定这里的正确语言,但是当方法被调用时,因为它们要么是委托方法,要么是作为观察者的目标而被调用的方法,它们是在主线程上执行的吗?

我想知道我是否可以在这些方法中更改UI,或者我是否必须将它们包装在

    dispatch_async(dispatch_get_main_queue(), ^{ UI stuff });

蒂雅:约翰。

对于委托,这可能会有所不同。如果文档没有指定,那么它们通常在主线程上发送。传统上,UIKit必须在主线程上使用,所以这些委托几乎总是从主线程调用。

对于通知,我认为你需要这个小剪辑。

通知中心以同步方式向观察者发送通知。换句话说,直到所有观察者都接收并处理了通知后,postNotification:方法才返回。要异步发送通知,使用NSNotificationQueue。在多线程应用程序中,通知总是在发出通知的线程中传递,该线程可能与观察者注册自己的线程不同

从http://developer.apple.com/library/mac/

文档/可可/引用/基金/类/nsnotificationcenter_Class/引用/Reference.html

最后对于KVO,通知可以来自其他线程。以下是一位苹果工程师对如何处理它们的看法。

http://lists.apple.com/archives/cocoa-dev/2007/May/msg00022.html

如前所述,线程将根据调用者的不同而变化。在你的委托方法中,如果你需要适应,你可以这样做:

if ([NSThread isMainThread]) {
    // do the UI stuff as normal
} else {
    dispatch_async(dispatch_get_main_queue(), ^{ UI stuff });
}

基本思想是,在所有情况下,观察者或委托方法在同一个线程中被调用,初始通知(对于观察者模式)或委托代码正在运行,所以如果你不确定,建议在主线程中调度UI块。我将在下面的推理中尝试证明这些陈述,当然我可能是错的。

除非在委托协议文档中明确指定,否则在委托模式中,在调用者正在运行的同一线程中直接调用方法。例如,如果调用者(委托对象)想要调用他的委托,并且当前正在"thread -1"上运行,那么调用将发生在同一个线程中:


// this is running in "Thread-1" --> then aDelegateMethod will continue on "Thread-1"
[myDelegate aDelegateMethod]

就观察者模式而言,我不认为系统有任何正当理由在主线程上显式地发送观察通知,特别是当引起通知的原始值更改在另一个线程中运行时。事实上,在KVO情况下,运行时通过添加一些私有方法来更改类定义,这些私有方法覆盖setter方法来执行通知,并且我没有看到在主线程中显式执行此调用的有效理由。因此,根据我的说法,KVO通知可以来自任何线程,并且该线程与在观察类中运行值更改的线程相同。

最后,基于NSNotificationCenter的机制看到他的通知被发布原始通知的同一个线程调用。这在苹果的文档中有明确的说明(值得一提的是,每个线程都有自己的通知队列)。

所以在所有情况下,线程都是维护的,如果你想确保你的UI块在主队列中被调用,那么使用你在问题中发布的GCD调用。

最新更新