SwiftUI中Date类型@State变量初始化报错,String类型却正常?
为何SwiftUI中使用Date等类型的@State变量初始化会失败?
这个问题的核心和SwiftUI的@State属性包装器特性、以及Swift编译器的初始化规则有关:
问题根源
@State是SwiftUI用来管理视图状态的属性包装器,编译器会自动为它生成一个底层的存储属性。对于有隐式默认值的类型(比如String默认是空串、Int默认是0、[Date]默认是空数组),编译器会自动完成@State底层存储的初始化。这时你在init里直接给stateValue赋值,本质是修改已经初始化完成的属性,所以不会触发编译错误。- 而
Date、包含Date的元组/自定义结构体、Any这类类型,编译器无法自动为它们生成@State的默认底层存储。此时直接给stateValue赋值,会被编译器判定为“在self完全初始化前使用了self”——因为底层的@State存储还没初始化,你就试图访问包装后的属性,因此报错。
解决方法
直接初始化@State对应的底层存储属性(以下划线_开头的变量),绕过包装后的属性访问:
struct DateDemoView: View { @State var stateValue: Date init(initialValue: Date) { _stateValue = State(initialValue: initialValue) } var body: some View { EmptyView() } }
对于其他初始化失败的类型,比如包含Date的自定义结构体,同样适用这个方法:
struct MyStruct { let string: String let date: Date } struct MyStructDemoView: View { @State var stateValue: MyStruct init(initialValue: MyStruct) { _stateValue = State(initialValue: initialValue) } var body: some View { EmptyView() } }
总结
当@State变量的类型无法让编译器自动生成默认底层存储时,必须通过下划线开头的底层变量来初始化State实例,而不是直接赋值包装后的属性。
内容的提问来源于stack exchange,提问作者fthdgn
相关产品推荐
相关产品推荐

