在返回值之前等待委托执行
Posted
技术标签:
【中文标题】在返回值之前等待委托执行【英文标题】:Wait for delegate execution before returning value 【发布时间】:2016-02-17 20:29:44 【问题描述】:我有一些带有 getter 和 setter 的类属性,它们向设备发送一些命令以设置或获取一些值。 CoreBluetooth 是异步工作的,例如,在返回值之前,我必须检查设备是否已响应命令,检查响应有效性,然后将值返回给调用者。
只是为了有个清晰的想法……
class A: Delegate
func peripheral(
peripheral: CBPeripheral,
didUpdateValueForCharacteristic characteristic: CBCharacteristic,
error: NSError?)
// receive some data, parse it and assign to lastResponse
A.lastResponse = ...
class A
static var lastResponse: SomeObject?
// get or set device name
static var name: String
get
// send command to device
...
// wait until a response is received
...
return lastResponse.value
set
// same as getter but have to ensure that the command
// has been received from device by checking the response code
我的想法是使用 NSCondition 对象等到条件变为真,但可能会冻结 UI。目标是等待异步函数/委托从同步函数执行而不冻结。
你知道怎么解决吗?
【问题讨论】:
不要等待。处理它是异步的事实。使用委托、回调闭包或 NSNotification 在委托中使用委托似乎不是一种更清洁的方式。完成处理程序被同步调用。可能 NSNotification 可能是问题解决者 我的选择可能是完成处理程序,但 NSNotification 也可以工作 好吧,你不能真正使用属性获取器,因为你的底层数据源是异步的。这取决于值是否可以通过 Bkuetooth 通知异步更新,以及是否有多个观察者想同时了解值的变化。在这些情况下,您将使用 NSNotification。如果只有一个观察者想要该值并且他们必须从设备请求该值,那么您可以将完成处理程序存储在由特征键控的字典中,发出读取,然后在读取完成时调用存储的完成处理程序 如果可能,完成处理程序将是一个完美的解决方案,但假设此代码为gist.github.com/luciocorsa/15c0862c129dd9c5ae74,您会注意到完成处理程序无法解决问题 【参考方案1】:一种可能的方法是不将 name 作为属性访问,而是编写一个方法调用来请求 name 并期望对它的委托调用,并在此委托调用中做任何你需要做的事情。
class protocol Delegate
func deviceName(name: String);
class A: Delegate
func peripheral(
peripheral: CBPeripheral,
didUpdateValueForCharacteristic characteristic: CBCharacteristic,
error: NSError?)
// receive some data, parse it and assign to lastResponse
A.lastResponse = ...
A.delegate = self
A.requestName()
func deviceName(name: String)
//do what u wish with the name
class A
static var lastResponse: SomeObject?
var delegate: Delegate?
// get or set device name
static var name: String?
func requestName()
...
// send command to device
...
// when a response is received
...
name = //name received
delegate.deviceName(name)
【讨论】:
以上是关于在返回值之前等待委托执行的主要内容,如果未能解决你的问题,请参考以下文章