数组中的 Swift 通用协议类类型

EDU*_*sta 3 ios swift swift-protocols

我们已经为我们的s实现了一个协议,Reusable以简化UITableView注册/出队实现UITableViewCell

protocol Reusable: class {
    static var defaultIdentifier: String { get }
}

extension Reusable where Self: UITableViewCell {
    static var defaultIdentifier: String {
        return String(describing: self)
    }
}

class TestTableViewCell: UITableViewCell, Reusable { }
class AnotherTestTableViewCell: UITableViewCell, Reusable { }
Run Code Online (Sandbox Code Playgroud)

然后,有一个扩展UITableView喜欢:

extension UITableView {
    func register<T: UITableViewCell & Reusable>(_: T.Type) {
        register(UINib(nibName: T.defaultIdentifier, bundle: nil), forCellReuseIdentifier: T.defaultIdentifier)
    }
}
Run Code Online (Sandbox Code Playgroud)

以及它的用法:

let tableView: UITableView = UITableView()
tableView.register(TestTableViewCell.self)
tableView.register(AnotherTableViewCell.self)
Run Code Online (Sandbox Code Playgroud)

一切正常,但我们想将这些类型移动到数组中,以便进行排序。这就是我们卡住的地方,这不起作用:

let viewCells = [TestTableViewCell.self, AnotherTestTableViewCell.self]
// Without type annotation, it's [UITableViewCell.Type]
// And the error is: Instance method 'register' requires that 'UITableViewCell' conform to 'Reusable'

for viewCell in viewCells {
    tableView.register(viewCell)
}
Run Code Online (Sandbox Code Playgroud)

我们也尝试过:

let viewCells: [Reusable.Type] = ...
// Error: Cannot invoke 'register' with an argument list of type '(Reusable.Type)'
Run Code Online (Sandbox Code Playgroud)

还有这个:

let viewCells: [(UITableViewCell & Reusable).Type] = ...
// Error: Instance method 'register' requires that 'UITableViewCell' conform to 'Reusable'
Run Code Online (Sandbox Code Playgroud)

有没有办法将具有协议一致性的类类型信息存储在数组中以使其工作?

Tom*_*kis 5

只需编写一个扩展,UITableViewCell使其符合Reusable协议并且不将单元格转换为任何类型:

extension UITableViewCell: Reusable {}
Run Code Online (Sandbox Code Playgroud)


PS 您还可以Reusable此处查看 iOS 上最流行的协议实现。


祝你好运 :)