SwiftUI中@available()与#available()的正确用法及iOS14运行崩溃问题
问题根因
你遇到的崩溃本质是属性包装器的初始化时机早于body内的版本判断执行时机导致的:
@FocusState是iOS 15才推出的API,虽然你给这个属性加了@available(iOS 15.0, *)标记,但这个标记只是编译层面的可用性检查,不会干预属性的初始化时机- SwiftUI的View是结构体,它的所有存储属性的初始化动作,会在结构体实例被创建的时候统一执行,不会等到body里的
if #available(iOS 15.0, *)判断走完才按需初始化iOS15专属属性 - 所以当iOS14设备运行时,App一初始化
ContentView就会尝试初始化@FocusState属性,但iOS14系统库里根本没有这个类,直接触发类不存在的崩溃,也就是你遇到的SIGABRT错误。
修复方案
把iOS15专属的逻辑封装到单独的带版本限制的View中,避免iOS14环境下触发FocusState的初始化:
import SwiftUI struct ContentView: View { @State private var text = "This app causes a runtime error on ios 14.7" var body: some View { if #available(iOS 15.0, *) { IOS15TextEditor(text: $text) } else { TextEditor(text: $text) } } } @available(iOS 15.0, *) struct IOS15TextEditor: View { @Binding var text: String @FocusState var isInputActive: Bool var body: some View { TextEditor(text: $text) .focused($isInputActive) } }
这种写法下,只有运行在iOS15及以上系统时才会实例化IOS15TextEditor,此时才会初始化@FocusState属性,完全规避iOS14下的初始化异常。
内容的提问来源于stack exchange,提问作者Koa
相关产品推荐
相关产品推荐

