You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift宏能否覆盖变量?线程安全懒加载宏实现求助

问题根源与解决办法

循环引用的核心是:宏生成的计算属性代码直接调用了被@Lazify标注的createLazyVariable()函数,而Swift宏展开时会递归处理带标注的实体——原函数带宏标注,生成的代码又引用它,编译器陷入循环处理的死循环。

解决思路是避免在生成代码中调用原标注函数,直接内联原函数的实现逻辑:

  1. 在宏解析阶段,提取createLazyVariable()函数的内部实现代码(即return "__" + NSStringFromClass(type(of: self))部分)。
  2. 生成计算属性代码时,将这部分实现直接替换掉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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 17:27:50