我试图声明一个由块组成的计算属性,在后台线程中执行。
因此,当我处理这个属性时,它是零,因为计算在未准备好时返回结果。如何更好地纠正这个问题?谢谢你!
enum Result<T> {
case error(error: Error)
case success(data: T)
}
var userID: Result<CKRecordID>? {
var result: Result<CKRecordID>? = nil
container.fetchUserRecordID { recordID, error in
if let error = error { result = .error(error: error) }
if let recordID = recordID { result = .success(data: recordID) }
}
return result
}
有一个直接的解决方案,例如使用 GCD 信号量。然而,整个方法一开始似乎并不正确,因为这可能会导致不必要的挂起,甚至在某些情况下死锁(例如在主线程中调用此属性)。更好的方法是将代码移动到具有适当完成处理程序的方法。
请记住,计算属性并不旨在取代方法。如果范围内有一些复杂(尤其是异步)计算,您几乎可以将该代码从属性移动到方法。
但不管怎么说:
var userID: Result<CKRecordID>? {
var result: Result<CKRecordID>? = nil
var sema = DispatchSemaphore(value: 0)
container.fetchUserRecordID { recordID, error in
if let error = error { result = .error(error: error) }
if let recordID = recordID { result = .success(data: recordID) }
sema.signal()
}
_ = sema.wait(timeout: .distantFuture)
return result
}
这里有一个等待异步操作完成的 GCD 信号量。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)