Swift宏能否覆盖变量?线程安全懒加载宏实现求助
问题根源与解决办法
循环引用的核心是:宏生成的计算属性代码直接调用了被@Lazify标注的createLazyVariable()函数,而Swift宏展开时会递归处理带标注的实体——原函数带宏标注,生成的代码又引用它,编译器陷入循环处理的死循环。
解决思路是避免在生成代码中调用原标注函数,直接内联原函数的实现逻辑:
- 在宏解析阶段,提取
createLazyVariable()函数的内部实现代码(即return "__" + NSStringFromClass(type(of: self))部分)。 - 生成计算属性代码时,将这部分实现直接替换掉
self.createLazyVariable()的调用。
修改后的展开代码示例:
private(set) var _lazy_internalClassName: String? = nil var internalClassName: String { if let exist = self._lazy_internalClassName { return exist } return SomeClass.classLock.around { [weak self] in guard let self else { fatalError() } if let exist = self._lazy_internalClassName { return exist } // 直接内联原函数逻辑,不再调用原函数 let temp = "__" + NSStringFromClass(type(of: self)) self._lazy_internalClassName = temp return temp } }
这样生成的代码不再依赖原标注函数,彻底打破循环引用。
如果需要保留原函数供其他地方调用,可以给原函数添加private访问控制,同时确保宏生成代码不引用它——但从你的场景来看,原函数的唯一作用是提供初始化逻辑,直接内联是最简洁的方案。
内容的提问来源于stack exchange,提问作者Klein Mioke
相关产品推荐
相关产品推荐

