问题涉及 Swift3 。
从版本4开始,您最终可以将对象强制转换为gvar
:
Type<Protocol>
我有一个协议和从中继承的多种类型。
someObject as (Type & Protocol)
对于该协议,我有一个对象继承自NSObject的情况:
扩展名是:
A, B, C, D: CKEntity (pseudocode)
多个案例的工作。
我有一个函数,它接受实现CKEntity的Class(Type)。
如果它也是NSObject,我需要检查它是否符合案例。 如果是,请调用相应的函数。
我想要完成的原型:
extension CKEntity where Self : NSObject {
static func method() {
...
}
不能工作。
问题是:
如何将类型(Protocol.Type)转换为NSObject.Type(不是实例)以满足扩展约束?
情景(概述):
A的扩展名,其中A是B
A可以是B
需要将A投射到A:B并到达受约束的A&amp; B界面。
答案 0 :(得分:0)
找到了解决方案,有点像。
当涉及到扩展 NSObject 时,最好是采用扩展 NSObjectProtocol 而不是NSObject本身(即使你&#39;重新扩展后者)。
原因是NSObject本身不是协议,这给Swift复合协议检查带来了困难。另一方面, NSObjectProtocol 自然地由任何NSObject派生的对象继承,并且是一个协议,这是一个关键。
因此,如果可能的话,我们应该重构将内容向下转换为多个协议的地方(如果可能的话,这可能是关于NSObject的)。
扩展修改如下:
extension NSObjectProtocol where Self : CKEntity {
static func method() {
// ...
}
}
支票是:
if let extendedType = type as? NSObjectProtocol & CKEntity.Type {
extendedType.self.method()
}
它有效!
可以偶然发现的缺点是NSObjectProtocol不包含KVC方法,因此您需要像这样投射对象以获得KVC接口:
extension NSObjectProtocol where Self : CKEntity {
static var staticVar : String {
return (Self.self as! NSObject.Type).className()
}
var publicVar : String! {
return (self as! NSObject).value(forKey: "Key") as! String
}
}