访问 ObservableObject 中的枚举

Accessing an enum in ObservableObject

我正在尝试重构我拥有的一些代码,并认为我能够将一些代码从可全局访问的枚举移动到应用程序的 ViewModel 中。

但是,当我尝试从视图访问它时,它似乎无法访问,甚至在自动完成中也没有选项。

我想知道出现这种情况是否有原因,我是否遗漏了什么..

// view
struct MyView: View {
 @StateObject var vm = MyViewModel()
 var body: some View {
  ForEach(vm.MyEnum.allCases, id: \.self) { item in
   ...
  }
 }
}

// view model
final class MyViewModel: ObservableObject {
 enum MyEnum: String, CaseIterable {
  case a, b, c
 }
}

我似乎能够访问视图模型中的所有其他内容,但在涉及枚举时却不能。我尝试阅读枚举以了解原因,但我遇到的大多数事情主要是“操作方法”,而没有深入探讨原因。

你的问题不是关于 enums,它更多的是关于属性与类型。当您这样做时:

final class MyViewModel: ObservableObject {
    enum MyEnum: String, CaseIterable {
        case a, b, c
    }
}

...您正在定义 2 种类型。

  1. MyViewModel,这是一个class
  2. MyEnum,这是一个 enum

您的 MyEnum 嵌套在 MyViewModel 中并不重要 — 它仍然只是一种类型,而不是 属性。

属性使用 letvar 声明。例如:

final class MyViewModel: ObservableObject {
    let myEnumArray = [MyEnum.a, MyEnum.b, MyEnum.c] /// create an instance property

    enum MyEnum: String, CaseIterable {
        case a, b, c
    }
}

struct MyView: View {
    @StateObject var vm = MyViewModel()
    var body: some View {

                /// access the instance property here!
        ForEach(vm.myEnumArray, id: \.self) { item in
            /// ...
        }
    }
}

在上面的代码中,我创建了一个新的 属性、myEnumArray,您可以使用 vm.myEnumArray 访问它。这会起作用。

现在如果您想访问 MyEnumallCases 怎么办?请注意,此 属性 是 static — 属性 属于类型本身,而不是类型的实例。这就是为什么它没有出现在您的自动完成中的原因。示例:

MyViewModel.MyEnum.allCases /// Works! The type is `MyViewModel.MyEnum` and I'm accessing the static `allCases` property.

@StateObject var vm = MyViewModel()
vm.MyEnum.allCases /// NO! the `MyEnum` property doesn't exist inside `vm`.

所以你的代码确实有 2 个问题。

  1. 你认为MyEnum是一个属性。不,是一种类型!
  2. 因为 MyEnum 是一种类型,所以您不能使用 vm.MyEnum 访问它(这就是您访问实例 属性 的方式)。你需要做 MyViewModel.MyEnum.

固定代码如下:

struct MyView: View {
    var body: some View {
        ForEach(MyViewModel.MyEnum.allCases, id: \.self) { item in
            /// ...
        }
    }
}