Swift中如何在Actor数组的first(where:)中访问隔离属性?
解决Actor隔离属性无法在非隔离上下文访问的问题
错误原因很明确:Swift Actor的所有属性默认都是隔离状态,只能在Actor自身的隔离代码块中直接访问。外部非隔离代码不能直接读取number这类隔离属性,必须通过异步调用Actor暴露的方法来获取或判断状态。
以下是两种可行的解决方案:
方案一:通过异步调用Actor的方法获取属性值
修改getCounter2为异步函数,手动遍历数组并通过await调用getNumber()方法来比较数值:
actor Counter{ var number:Int init(number: Int) { self.number = number } func getNumber() -> Int { return number } } var counters:[Counter] = [] func addCounter(){ for i in 1...10 { let counter = Counter(number: i ) counters.append( counter ) } } // 改为异步函数,遍历并逐个await判断 func getCounter2(number: Int) async -> Counter? { for counter in counters { if await counter.getNumber() == number { return counter } } return nil }
注:不能直接用first(where:),因为该方法的闭包是同步的,不支持异步调用await。
方案二:给Actor添加封装的异步判断方法
把匹配逻辑封装到Actor内部,外部只需调用异步的判断方法,更符合Actor的封装原则:
actor Counter{ var number:Int init(number: Int) { self.number = number } // 封装判断逻辑到Actor内部 func isEqual(to target: Int) async -> Bool { return number == target } } var counters:[Counter] = [] func addCounter(){ for i in 1...10 { let counter = Counter(number: i ) counters.append( counter ) } } func getCounter2(number: Int) async -> Counter? { for counter in counters { if await counter.isEqual(to: number) { return counter } } return nil }
使用时需要在异步上下文调用getCounter2,比如:
Task { if let counter = await getCounter2(number: 5) { print("找到目标Counter") } }
内容的提问来源于stack exchange,提问作者reza23
相关产品推荐
相关产品推荐

