当计算使用后台线程时,如何正确声明一个计算属性? [英] How to properly declare a computed property, when calculation uses background threads?

查看:84
本文介绍了当计算使用后台线程时,如何正确声明一个计算属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试声明一个包含在后台线程中执行的块的计算属性. 因此,当我处理此属性时,它为nil,因为计算未准备好时会返回结果.如何更好地纠正这一点?谢谢!

I'm trying to declare a computed property that consists of a block, executed in the background thread. So, when I address this property, it's nil, as the computation returns the result when it is not ready. How to better correct this? Thank you!

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信号灯.但是,整个方法最初似乎并不正确,因为在某些情况下(例如在主线程中调用此属性),这可能会导致不必要的挂起甚至死锁.更好的方法是将代码移至具有适当完成处理程序的方法.

There's a straight-forward solution, such as using GCD semaphores. However, the entire approach doesn't seem correct in the first place, for this might cause unwanted hangs or even deadlocks in some circumstances (like calling this property in main thread). The better approach would be moving that code to a method with appropriate completion handler.

请记住,计算的属性并非旨在替代方法.如果范围内有一些复杂的(特别是异步)计算,则可以将代码从属性移到方法上了.

Just keep in mind that computed properties are not intended to replace methods. If there are some complex (especially asynchronous) calculations in the scope, you're pretty much set to move that code from a property to a method.

但是无论如何:

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信号灯.

Here you have a GCD semaphore which awaits for async operation to finish.

这篇关于当计算使用后台线程时,如何正确声明一个计算属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆