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
属性 来更新心率。 heartRate
在 peripheral: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];
如果你参考initWithDelegate
的queue
参数的文档,它说-
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 更新事件
我有 OSX BLE 心率示例来自:https://developer.apple.com/library/mac/samplecode/HeartRateMonitor/Introduction/Intro.html。此示例通过将 NSTextField 绑定到 heartRate
属性 来更新心率。 heartRate
在 peripheral:didUpdateValueForCharacteristic
中更新,相应地更新绑定的 NSTextView。 peripheral:didUpdateValueForCharacteristic
不在另一个线程上,但这工作正常,因为控件的更新由 Cocoa?
我添加了另一个 NSTextView,并在其中创建了一个 outlet ivar。此 ivar 也会在 peripheral:didUpdateValueForCharacteristic
中更新并调用 [txtfldHR setIntegerValue:bpm];
。这似乎也能正常工作。但是从另一个线程通过 IBOutlet 更新 NSTextField 是不是危险的(或者根本不应该工作)?如何在不使用绑定的情况下通过函数调用安全地更新 NSTextField?
我在 Android 中制作了一个类似的应用程序,我需要通过消息将心率值从 BLE 回调传递到 UI 线程以更新 UI 控件。
如果您查看示例代码,您会发现 CBCentralManager
是使用以下代码初始化的 -
manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
如果你参考initWithDelegate
的queue
参数的文档,它说-
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 });