[英]How to use protocol extension to provide auto-generated identifier for classes?
I want to provide an auto-generated identifier for each custom UITableViewCell subclass. 我想为每个自定义UITableViewCell子类提供一个自动生成的标识符。 I try the following code, but the compiler says 我尝试以下代码,但是编译器说
type 'T' has no member 'autoReuseIdentifier' 类型“ T”没有成员“ autoReuseIdentifier”
protocol AutoReusable: class {
static var autoReuseIdentifier: String { get }
}
extension AutoReusable {
static var autoReuseIdentifier: String {
return "\(self)"
}
}
extension UITableViewCell: AutoReusable {}
func printClassName<T: UITableViewCell>(type type: T.Type) {
print(T.autoReuseIdentifier)
}
It's okay to implement the protocol in an extension for UITableViewCell, but I prefer to implement it in a protocol extension. 可以在UITableViewCell的扩展中实现协议,但我更喜欢在协议扩展中实现。 How to fix this? 如何解决这个问题?
The generic T
in printClassName(...)
does not know that it conforms to AutoReusable
protocol (even if you, as the developer, knows that UITableViewCell
does so), it only knows that it is a UITableViewCell
och UITableViewCell
subclass object. printClassName(...)
中的泛型T
不知道它符合AutoReusable
协议(即使您(作为开发人员)知道UITableViewCell
也是这样),它也仅知道它是UITableViewCell
UITableViewCell
子类对象。
You could redeem this by adding a ... where T: AutoReusable>
in the generic type constraint of printClassName(...)
您可以在printClassName(...)
的通用类型约束中添加一个... where T: AutoReusable>
来赎回它printClassName(...)
func printClassName<T: UITableViewCell where T: AutoReusable>(type type: T.Type) {
print(T.autoReuseIdentifier)
}
A more common implementation of printClassName(...)
would be, however, to constraint T
to the protocol AutoReusable
, rather than let printClassName
be a function specifically for UITableViewCell
objects (subclass objects) 但是, printClassName(...)
更常见实现是将T
约束到协议AutoReusable
,而不是让printClassName
作为专门用于UITableViewCell
对象(子类对象)的函数。
func printClassName<T: AutoReusable>(type type: T.Type) {
print(T.autoReuseIdentifier)
}
This generic function can then be called from any type conforming to AutoReusable
, whereas you can control the default implementation of autoReuseIdentifier
by different extensions to the protocol AutoReusable
. 然后可以从符合AutoReusable
任何类型调用此泛型函数,而您可以通过对协议AutoReusable
不同扩展来控制autoReuseIdentifier
的默认实现。 Eg, as a complete example: 例如,作为一个完整的示例:
protocol AutoReusable: class {
static var autoReuseIdentifier: String { get }
}
/* Default implementation */
extension AutoReusable {
static var autoReuseIdentifier: String {
return "\(self)"
}
}
/* Default implementation specifically for UITableViewCell (and subclasses) */
extension AutoReusable where Self: UITableViewCell {
static var autoReuseIdentifier: String {
return "\(self) (UITableViewCell)"
}
}
/* Generic function invokable by any class type conforming to printClassName */
func printClassName<T: AutoReusable>(type type: T.Type) {
print(T.autoReuseIdentifier)
}
/* Example setup */
extension UITableViewCell: AutoReusable { }
class Foo : AutoReusable { }
class MyCell : UITableViewCell {}
/* Example usage */
let foo = Foo()
let bar = MyCell()
printClassName(type: foo.dynamicType) // Foo
printClassName(type: bar.dynamicType) // MyCell (UITableViewCell)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.