如何将协议转换为 NSObject<Protocol> 以访问受限扩展接口?
How to cast Protocol to NSObject<Protocol> to access constrained extension interface?
问题参考Swift3。
从版本 4 开始,您终于可以像这样将对象转换为 Type<Protocol>
:
someObject as (Type & Protocol)
我有一个协议和多个继承自它的类型。
A, B, C, D: CKEntity (pseudocode)
对于该协议,我有一个对象继承自 NSObject 的情况:
分机号是:
extension CKEntity where Self : NSObject {
static func method() {
...
}
适用于多种情况。
我有一个函数采用 Class(Type) 实现 CKEntity。
如果也是NSObject,我需要检查是否符合大小写。
如果是,调用适当的函数。
我想要完成的原型:
func validateSync(ofType type: CKEntity.Type) {
let a = (type as NSObject.Type & CKEntity.Type).self
a.method() // Compilation error: Type 'Any' has no member 'method'
}
无效。
问题是:
如何将类型 (Protocol.Type) 转换为 NSObject.Type(不是实例)以满足扩展约束?
场景(回顾):
A 的扩展名,其中 A 是 B
A可以是B
需要将 A 转换为 A:B 并达到受约束的 A&B 接口。
解决方案找到了,有点。
问题在于,在扩展 NSObject 时,最好求助于扩展 NSObjectProtocol 而不是 NSObject 本身(即使您将要扩展后者)。
原因是 NSObject 本身不是协议,这给 Swift 复合协议检查带来了困难。 NSObjectProtocol,另一方面,自然被任何NSObject派生的对象所继承,是一个协议,是一个key
因此,如果可能的话(这是可能的,如果它是关于 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
}
}
问题参考Swift3。
从版本 4 开始,您终于可以像这样将对象转换为 Type<Protocol>
:
someObject as (Type & Protocol)
我有一个协议和多个继承自它的类型。
A, B, C, D: CKEntity (pseudocode)
对于该协议,我有一个对象继承自 NSObject 的情况:
分机号是:
extension CKEntity where Self : NSObject {
static func method() {
...
}
适用于多种情况。
我有一个函数采用 Class(Type) 实现 CKEntity。
如果也是NSObject,我需要检查是否符合大小写。 如果是,调用适当的函数。
我想要完成的原型:
func validateSync(ofType type: CKEntity.Type) {
let a = (type as NSObject.Type & CKEntity.Type).self
a.method() // Compilation error: Type 'Any' has no member 'method'
}
无效。
问题是:
如何将类型 (Protocol.Type) 转换为 NSObject.Type(不是实例)以满足扩展约束?
场景(回顾):
A 的扩展名,其中 A 是 B
A可以是B
需要将 A 转换为 A:B 并达到受约束的 A&B 接口。
解决方案找到了,有点。
问题在于,在扩展 NSObject 时,最好求助于扩展 NSObjectProtocol 而不是 NSObject 本身(即使您将要扩展后者)。
原因是 NSObject 本身不是协议,这给 Swift 复合协议检查带来了困难。 NSObjectProtocol,另一方面,自然被任何NSObject派生的对象所继承,是一个协议,是一个key
因此,如果可能的话(这是可能的,如果它是关于 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
}
}