Xcode 14 beta报存储属性无法用@available标记错误如何解决
问题表现
- 编译环境:Xcode 14 beta,操作
.xcworkspace文件执行编译 - 编译报错:
Stored properties cannot be marked potentially unavailable with '@available' - 相同代码在Xcode 13环境下可正常编译运行,无该报错
根因说明
Xcode 14 内置的Swift 5.7编译器正式落地了存储属性的可用性校验规则:存储属性不能直接使用@available标记限定系统版本可用性。
该规则在Swift 5.6及更早版本(对应Xcode 13及更早)中仅作为警告提示,不会阻断编译;从Swift 5.7开始升级为编译错误。本质是因为带版本可用性的存储属性会导致类/结构体的实例内存布局随系统版本变化,存在运行时内存风险,因此编译器直接禁止了这种写法。
修复方案
根据属性的实际使用场景选对应方案即可:
方案1:无状态属性改为计算属性
如果标记可用性的属性不需要持有持久状态,直接将存储属性改为计算属性,计算属性不受@available使用限制:
// 原报错写法(存储属性) @available(iOS 15.0, *) let qrCodeDetector = QRCodeDetector() // 修复后写法(计算属性) @available(iOS 15.0, *) var qrCodeDetector: QRCodeDetector { QRCodeDetector() }
方案2:需要持状态的属性拆分存储与访问逻辑
如果属性需要持久持有初始化后的实例,不要直接在存储属性上标记@available,拆分出内部存储属性,将可用性标记放到对外访问的计算属性上:
// 原报错写法 @available(iOS 15.0, *) let focusFilter = FocusEffectFilter() // 修复后写法 private lazy var _focusFilter: FocusEffectFilter = { guard #available(iOS 15.0, *) else { fatalError("FocusEffectFilter is only available on iOS 15.0+") } return FocusEffectFilter() }() @available(iOS 15.0, *) var focusFilter: FocusEffectFilter { _focusFilter }
如果属性仅在对应可用版本的代码分支内被调用,fatalError分支不会触发,无运行时风险。
方案3:OC混编场景适配
如果是OC混编项目中导入OC声明的属性触发该报错,检查OC属性的NS_AVAILABLE标记是否直接打在了属性声明上,可将版本校验逻辑挪到属性的getter/setter方法实现中,头文件只暴露普通属性声明即可。
内容的提问来源于stack exchange,提问作者bmeikle
相关产品推荐
相关产品推荐

