从Actor隔离函数调用协议扩展异步函数,是否保持隔离性?
Actor协议扩展异步函数的执行上下文与生命周期问题
代码示例
protocol Foo { func foo() async } extension Foo { func foo() async { print("default implementation") } } final actor Bar: Foo { func run() async { print("this function is isolated on actor Bar") await self.foo() } }
前提说明
- 协议
Foo通过扩展提供了异步函数foo的默认实现 - Actor类型
Bar遵循Foo协议 Bar的隔离方法run中调用了foo,且该调用指向协议扩展的默认实现
问题解答
1. foo的执行上下文
foo函数会在Bar Actor的执行上下文中运行。
协议扩展的默认方法会继承调用者的隔离上下文:调用self.foo()时,self是Bar的实例,处于Bar的Actor隔离域内,因此默认实现的foo会在该Actor的执行队列上执行。你可以添加打印验证:
extension Foo { func foo() async { print("default implementation, current actor: \(Actor.current)") } }
运行后会输出当前Actor为Bar实例,直接证明执行上下文归属Bar。
2. Actor的释放风险
不会出现因异步调用超出作用域导致Bar被释放的情况。
run是Bar的隔离方法,在await self.foo()执行期间,self(即Bar实例)会被任务持有,直到foo的异步操作完成。Actor的生命周期由引用计数管理,只要存在未完成的异步任务持有它的引用,就不会被释放。
内容的提问来源于stack exchange,提问作者Isaaс Weisberg
相关产品推荐
相关产品推荐

