OSX Cocoa Core-Bluetooth 委托和 UI 更新线程安全

OSX Cocoa Core-Bluetooth delegate and UI update thread safety

我有 OSX BLE 心率示例来自:https://developer.apple.com/library/mac/samplecode/HeartRateMonitor/Introduction/Intro.html。此示例通过将 NSTextField 绑定到 heartRate 属性 来更新心率。 heartRateperipheral:didUpdateValueForCharacteristic 中更新,相应地更新绑定的 NSTextView。 peripheral:didUpdateValueForCharacteristic 不在另一个线程上,但这工作正常,因为控件的更新由 Cocoa?

处理 'behind the scenes'

我添加了另一个 NSTextView,并在其中创建了一个 outlet ivar。此 ivar 也会在 peripheral:didUpdateValueForCharacteristic 中更新并调用 [txtfldHR setIntegerValue:bpm];。这似乎也能正常工作。但是从另一个线程通过 IBOutlet 更新 NSTextField 是不是危险的(或者根本不应该工作)?如何在不使用绑定的情况下通过函数调用安全地更新 NSTextField?

我在 Android 中制作了一个类似的应用程序,我需要通过消息将心率值从 BLE 回调传递到 UI 线程以更新 UI 控件。

如果您查看示例代码,您会发现 CBCentralManager 是使用以下代码初始化的 -

manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];

如果你参考initWithDelegatequeue参数的文档,它说-

The dispatch queue to use to dispatch the central role events. If the value is nil, the central manager dispatches central role events using the main queue.

这意味着您的各种蓝牙委托事件将使用主队列执行。

如果您为委托操作使用不同的队列,那么您需要通过 dispatch_async(dispatch_get_main_queue() ^{ //code });

之类的方式在主队列上显式分派 UI 更新事件