说我有:
@objc public protocol InteractivelyNameable: Nameable {
static func alertViewForNaming(_ existingObject: Nameable?,
context: NSManagedObjectContext,
completion:@escaping ((_ success: Bool, _ object: Nameable?, _ didCancel: Bool, _ error: Error?) -> Void)) -> UIAlertController?
}
我有一个管理各种类型的通用视图控制器(泛型类型是.fetchableObjectType ...基本上是NSManagedObject.self
..好吧,它的子类)。我需要检查特定对象类型是否符合协议,如果是,请调用它。
类似的东西:
// valid swift code
if self.dataSource.fetchableObjectType is InteractivelyNameable {
// not valid swift code
if let alert = (self.dataSource.fetchableObjectType as! InteractivelyNameable).alertViewForNaming(....) { // ... do stuff }
}
答案 0 :(得分:0)
要将类型转换为“类级别”的协议,您可以使用协议本身的.Type属性。
if let type = self.dataSource.fetchableObjectType as? InteractivelyNameable.Type {
if let alert = type.alertViewForNaming(nil, context: self.dataSource.managedObjectContext, completion: completion) {
// this code finds itself inside a UIViewController subclass...
self.present(alert, animated: true, completion: nil)
return
}
}
通用表格摘要:
if let myConformingObject = someObject as? InteractivelyNameable {
// invoke instance methods...
myConformingObject.someInstanceMethodDefinedInProtocol()
// invoke class methods
type(of: myConformingObject).someClassMethodDefinedInProtocol()
}
// i.e. someTypeParameter = NSManagedObject.Type
if let conformingType = someTypeParameter as? InteractivelyNameable.Type {
conformingType.someClassMethodDefinedInProtocol()
}
答案 1 :(得分:0)
您编写的静态方法不是generic,而是协议作为类型参数。 基本上,当您用作协议类型参数而不是通用表单时,强制编译器使用dynamic dispatcher,ergo,Objective-C。
为了使用静态类型调度程序(Swift),您需要做什么:
static func alertViewForNaming<T : Nameable>(_ existingObject: T,
context: NSManagedObjectContext,
completion:@escaping ((_ success: Bool, _ object: T, _ didCancel: Bool, _ error: Error?) -> Void)) -> UIAlertController?
这是一个通用的type constraint方法,在这种情况下,它是协议类型约束AKA Nameable
。
您可以按如下方式调用静态方法:
let test : ObjectThatConformsToNameableProtocol = InteractivelyNameable.alertViewForNaming.....
这样,编译器可以推断泛型类型方法的类型,在本例中为ObjectThatConformsToNameableProtocol
。
我没有测试代码,但了解泛型和协议类型参数之间的区别非常重要。