【问题标题】:Is CADisplayLink callback always runs on the main thread?CADisplayLink 回调是否总是在主线程上运行?
【发布时间】:2019-08-02 08:50:40
【问题描述】:

我在网上和文档中都找不到任何直接答案。 如果我使用以下内容设置CADisplayLink

 let displayLink = CADisplayLink(target: self, selector: #selector(updateShimmer))
 displayLink.add(to: .current, forMode: .common)

@objc func updateShimmer() {
   print(Thread.isMainThread)
}

我说实话。我知道我可以将其包装在 DispatchQueue.main 中,但我想知道,它是否总是在主队列中调度?还是我应该把它包起来?

【问题讨论】:

    标签: ios callback grand-central-dispatch cadisplaylink


    【解决方案1】:

    您无需手动将显示链接处理程序中的代码分派到主线程。添加到特定运行循环的计时器和显示链接将始终在与该运行循环关联的线程上运行。如需更多信息,请参阅Threading Programming Guide: Run Loops

    归根结底,如果你add(to:forMode:) 到主运行循环,主运行循环总是在主线程上运行。

    话虽如此,如果您想确保它始终在主线程上运行,我建议明确并将其添加到.main,而不仅仅是.current。这消除了任何歧义:

    let displayLink = CADisplayLink(target: self, selector: #selector(updateShimmer(_:)))
    displayLink.add(to: .main, forMode: .common)
    

    注意,我还调整了updateShimmer 的签名以接受参数。显示链接将传递给它。在方法中包含该引用通常很有用。而且,无论如何,它使代码更加不言自明:您现在只需看一下这个方法,就会明白这是一个显示链接处理程序:

    @objc func updateShimmer(_ displayLink: CADisplayLink) {
         ...
    }
    

    【讨论】:

    • 完美,罗伯。感谢您提供的重要信息,一如既往的感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多