2017-09-15 54 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