通用访问函数协议 class

Access function protocol in generic class

我想访问协议中的功能,但是XCode投诉

Instance member 'createColumns' cannot be used on type 'T'; did you mean to use a value of this type instead?

我做了什么:

创建协议:

protocol StorageModelDelegate {
   func createColumns(for tableBuilder: TableBuilder)
}

创建 class 接收 StorageModelDelegate 的泛型:

class SQLiteStorage<T: StorageModelDelegate> {
     func createTable(tableName: TableKey) -> Bool {
           let table = Table(tableName.rawValue)

           let query = table.create(ifNotExists: true) { (builder: TableBuilder) in
                T.createColumns(for: builder) // -> this is the error comes up.
           }
     }
}

创建 class 实现 SQLiteStorage:

final class InfoStorageModel {
    private let sqlite: SQLiteStorage = SQLiteStorage<Info>()
}

那么,如何修复 SQLiteStorage 中的错误 class?

该错误表明您需要 T 实例 ,而不是 类型 本身。

所以你需要这样的东西:

class SQLiteStorage<T: StorageModelDelegate> {
    var delegate:T

    init (delegate:T) {
      self.delegate = delegate
    }

    func createTable(tableName: TableKey) -> Bool {
          let table = Table(tableName.rawValue)

          let query = table.create(ifNotExists: true) { (builder: TableBuilder) in
                self.delegate.createColumns(for: builder) // -> this is the error comes up.
          }
    }
}

您想调用静态方法而不是实例方法。

为了修复,您应该添加实例参数:

首先,使用弱变量委托来防止循环引用。

protocol StorageModelDelegate: class {
   func createColumns(for tableBuilder: TableBuilder)
}

final class SQLiteStorage<T: StorageModelDelegate> {
weak var delegate: T?
     func createTable(tableName: TableKey) -> Bool {
           let table = Table(tableName.rawValue)

           let query = table.create(ifNotExists: true) { (builder: TableBuilder) in
                delegate?.createColumns(for: builder)
           }
     }
}

或者使用静态协议方法:

protocol StorageModelDelegate {
   static func createColumns(for tableBuilder: TableBuilder)
}


final class SQLiteStorage<T: StorageModelDelegate> {
weak var delegate: T?
     func createTable(tableName: TableKey) -> Bool {
           let table = Table(tableName.rawValue)

           let query = table.create(ifNotExists: true) { (builder: TableBuilder) in
                T.createColumns(for: builder)
           }
     }
}