【问题标题】:How do I use an existing property in a property wrapper when self hasn't been initialized? (SwiftUI)当 self 尚未初始化时,如何在属性包装器中使用现有属性? (SwiftUI)
【发布时间】:2020-07-13 19:59:14
【问题描述】:

我在属性包装器中有一个包含两个变量的结构。其中一个变量应该是从另一个变量中计算出来的。当我尝试这样做时,我收到以下错误:

不能在属性初始化器中使用实例成员“名称”;属性初始化程序在 'self' 可用之前运行。

我尝试为这些变量分配一个临时值,然后在自定义 init() 函数中重新分配它们,但这似乎不起作用。我做了一个简化版本的代码,看看我是否可以隔离问题。

import SwiftUI

struct Person {
    @State var name: String = ""
    @State var nameTag: NameTag = NameTag(words: "")
    
    init(name: String) {
        // not changing name and nameTag
        self.name = name
        nameTag = NameTag(words: "Hi, my name is \(name).")
    }
}


class NameTag {
    var words: String
    
    init(words: String) {
        self.words = words
    }
}


var me = Person(name: "Myself")
// still set to initial values
me.name
me.nameTag.words

我注意到,当我将 nameTag 更改为 @ObservedObject 而不是 @State 时,它能够被正确地重新分配。虽然我不相信我可以将名字改为@ObservedObject。谁能告诉我我做错了什么?

【问题讨论】:

标签: swift swiftui self initializer property-wrapper


【解决方案1】:

要在初始化器中使用属性包装器,您可以使用带有前下划线的变量名。

对于 State,您可以使用 init(initialValue:)

struct Person {
  @State var name: String
  @State var nameTag: NameTag

  init(name: String) {
    _name = .init(initialValue: name)
    _nameTag = .init( initialValue: .init(words: name) )
  }
}

这是 @State 属性的真实样子,因为您分解了语法糖的级别:

name
_name.wrappedValue
$name.wrappedValue
_name.projectedValue.wrappedValue

您不能在初始类型定义之外使用下划线名称。

【讨论】:

  • 在这种情况下如何使用下划线“_”?我以前从未见过它们被这样使用。谢谢!
猜你喜欢
  • 2020-06-18
  • 2019-12-02
  • 2021-06-21
  • 2017-03-03
  • 2012-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多