类型“T”的值没有使用根类型“T”的键路径的动态成员“对象”

Spa*_*Dog 5 generics protocols swift

我有一堂课是这样的:

class ObjectA:ObservableObject { 
  @Published var type:ObjectSheetType = .none
}
Run Code Online (Sandbox Code Playgroud)

我正在使用这样的类来处理此类对象的实例:

class ProcessObject {

  @ObservedObject private var object:ObjectA

  init(object:ObjectA) {
    self.object = object
  }

  process() {
    if object.type == .big {
     // bla bla
    }
    ...
  }
Run Code Online (Sandbox Code Playgroud)

然后我决定添加另一个类:

class ObjectB:ObservableObject { 
  @Published var type:ObjectSheetType = .none
}
Run Code Online (Sandbox Code Playgroud)

和一个协议

protocol ObjectProtocol {
  var type:ObjectSheetType { get set }
}
Run Code Online (Sandbox Code Playgroud)

该协议已添加到以下两个类中:ObjectAObjectB

ProcessObject然后修改该类以接受两种类型的对象:

class processObject<T:ObjectProtocol, ObservableObject > {

  @ObservedObject private var object:T

  init(object:T) {
    self.object = object
  }
Run Code Online (Sandbox Code Playgroud)

错误:引用下标“subscript(dynamicMember:)”需要包装器“ObservedObject.Wrapper”插入“$”类型“T”的值没有使用根类型“T”的键路径的动态成员“对象”

错误指向

if object.type == .big {
Run Code Online (Sandbox Code Playgroud)

object而且 Xcode 还希望我在?的每个已发布属性前面使用 $

我该如何解决这个问题?

Joa*_*son 4

您需要做的就是修复 T 的协议一致性,因为现在 ObservableObject 被视为另一种泛型类型而不是协议。

使用 & 表示 T 应该符合两个协议

class ProcessObject<T: ObjectProtocol & ObservableObject> {

}
Run Code Online (Sandbox Code Playgroud)

另一种方法是说 ObjectProtocol 继承自 ObservableObject,然后仅在所有符合声明中使用 ObjectProtocol

protocol ObjectProtocol: ObservableObject {
    var type:ObjectSheetType { get set }
}
Run Code Online (Sandbox Code Playgroud)

但这改变了 ObjectProtocol 的含义,您可能不希望两个协议之间存在紧密耦合