2017-09-15 58 views
0

调用泛型类型符合约定的一个静态方法来一个协议说我有:如何斯威夫特

@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

要在“职业等级”蒙上类型的协议,您可以使用该协议本身的.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() 
    } 
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

我没有测试代码,但了解泛型和协议类型参数之间的区别很重要。

+0

你的一种方法看起来不错。 这是如何工作在我想要完成的范围内?想象一下NSFetchedResultsController管理NSManagedObject的特定子类。所以我知道它正在管理的对象的类型,但是说我没有实例。我想知道它的类是否符合InteractivelyNameable,如果是,请给我一个UIAlertController。 – horseshoe7

+0

我认为你的问题是你使用具体类型。你不应该使用具体的类型,例如,使用一个Nameable协议的数组,这样你就知道实际的协议类型。当然,如果你使用具体类型,你将有类型问题验证。您在回答中写入的解决方案违反了来自SOLID btw的LSP原理。 – OhadM

+0

SOLID中的LSP原理究竟是什么? 我现在必须使用混凝土类型。 – horseshoe7