【问题标题】:Why performSelector:onThread: is not good?为什么 performSelector:onThread: 不好?
【发布时间】:2015-01-04 08:20:22
【问题描述】:

刚刚在Apple docs:找到

注意:虽然适用于线程间的偶尔通信,但您不应将performSelector:onThread:withObject:waitUntilDone: 方法用于线程间时间紧迫或频繁的通信。

为什么会这样? “频繁”是多少?

我有一个应用程序,它有很多线程,并且在主线程中发生了很多事情(大量的 JavaScript,WebKit 中频繁的 Ajax 查询)。在 Yosemite 上,我开始遇到多个(比如 10 个)文件下载 (NSURLDownloads) 和 WebKit GUI(需要在主线程中运行)组合的巨大问题。

对于由 JavaScript 大量加载的 WebKit,文件下载无法“存活”很长时间。在某些时候,所有网络请求都会开始返回超时(错误 -1001),直到应用退出。

我广泛使用performSelector:onThread:withObject:waitUntilDone:,例如通知 UI 下载进度。这可以每秒发生多次。会不会是问题?

附:不幸的是,我不允许展示整个源代码...

【问题讨论】:

    标签: multithreading cocoa


    【解决方案1】:

    奇怪的是,在 Yosemite 文档中,NSObject 的文档中并没有这样的警告...

    虽然也许只有苹果才能给出真正的原因,但我怀疑这与性能有关。请注意NSObject 中该调用的文档中的这一段:

    此方法使用默认运行循环模式(即与NSRunLoopCommonModes 常量关联的模式)在目标线程的运行循环上对消息进行排队。作为其正常运行循环处理的一部分,目标线程将消息出列(假设它以默认运行循环模式之一运行)并调用所需的方法。

    换句话说,当您使用该方法时,您在系统上的不同线程上传递对象,并且在此过程中可能存在一些开销。系统只保证它会被目标线程直接执行——它没有说什么时候它会被执行。如果目标线程已经在做某事,你的方法可能有一段时间不会被调用。因此,最好将消息发送到线程(即更新标志或其他东西)而不是立即运行某些东西,因为就像所有带有线程的东西一样,不能保证立即执行。

    总而言之,警告可能有两个原因:

    • 这样做会产生一些开销,因此不适合发送快速消息
    • 无法保证该方法何时执行;这一切都取决于 CPU 调度程序何时给线程执行时间以及发生这种情况时线程正在做什么

    【讨论】:

    • 我可以理解一些延迟,好吧。但是,正如我所说,网络变得完全没有响应。所以我想,可能还有另一个原因。也许是优胜美地特有的错误......
    猜你喜欢
    • 1970-01-01
    • 2011-01-24
    • 1970-01-01
    • 2013-07-23
    • 2010-09-12
    • 1970-01-01
    • 2011-11-25
    • 2016-03-02
    • 2018-11-06
    相关资源
    最近更新 更多