是什么引起了这个? - " CoreAnimation:警告,已删除的线程与未提交的CATransaction"

时间:2017-02-08 12:52:59

标签: swift xcode macos

Xcode 8.2.1 / macOS 10.12.4 beta

我试图了解我遇到的错误:

CoreAnimation: warning, deleted thread with uncommitted CATransaction; set CA_DEBUG_TRANSACTIONS=1 in environment to log backtraces, or set CA_ASSERT_MAIN_THREAD_TRANSACTIONS=1 to abort when an implicit transaction isn't created on a main thread.

我在swift文件中有一段代码,它发送网络请求,检索一些数据并在发布通知之前对其进行处理:

// global variable
var data: [String: Any] = [:]

func requestData() {
    ...
    do {
        // process data              
        data = processedData                        
        NotificationCenter.default.post(name: didProcessData, object: nil)
        }
    } catch {
        ...
    }

在我的主ViewController.swift文件中,观察者监听通知并更新视图。

func updateView() {
    // update the view
    textField.stringValue = "..."
}

override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector: #selector(updateView), name: didProcessData, object: nil)

}

调用updateView()时,实际文本字段等会花费一段时间实际更新,并出现上述错误。

我的猜测是线程安全存在问题,因此我更改了updateView()

func updateView() {
    DispatchQueue.main.async(execute: {
        // update the view
        self.textField.stringValue = "..."
    })
}

现在视图正确更新了。但是我对编程仍然相对缺乏经验,而且我不太明白究竟是什么导致了错误。

1 个答案:

答案 0 :(得分:1)

您的通知处理程序(updateView)是从任意线程调用的 - 例如而不是来自主线程(所谓的 UI-Thread )。几个框架API检测何时从主线程外部调用它们(作为一种警告)。

如果要更新UI,您必须确保在主线程中执行此代码;这通常是通过将一个闭包(工作项)排入DispatchQueue.main.async来完成的,这是GCD(Grand Central Dispatch)的一部分。