2015-08-28 68 views
2

我正在構建iOS應用程序的狀態恢復。我目前有動態檢查Swift 2中的對象類型

func application(application: UIApplication, viewControllerWithRestorationIdentifierPath identifierComponents: [AnyObject], coder: NSCoder) -> UIViewController? { 

    guard let controllerIdentifier = identifierComponents.last as? String else { 
     return nil 
    } 

    guard let ctrl = self.window?.rootViewController else { 
     return nil 
    } 

    if controllerIdentifier == "SetupPagesViewController" && ctrl is SetupPagesViewController { 
     return ctrl 
    } else if controllerIdentifier == "MainViewController" && ctrl is MainViewController { 
     return ctrl 
    } 

    return nil 
} 

在哪裏我發現最後一行有點難看。我可能會有更多的if這將永遠返回控制器。我試圖找到一個構造,我不會擁有所有那些if s。

我試圖用之類的東西:

let checks = [ 
     "SetupPagesViewController": SetupPagesViewController.self, 
     "MainViewController": MainViewController.self, 
    ] 

    if let clazz = checks[controllerIdentifier] where ctrl is clazz { 
     return ctrl 
    } 

但是編譯器不會讓我。我無法找到存儲我的class類型的方法,以便在if中重複使用它。

這可能嗎?怎麼樣?由於

回答

0

想到這SWIFTY方法會爲你工作:

func checkController(controllerIdentifier: String, ctrl: Any) -> UIViewController? { 
    let objectList: [String:Any.Type] = [ 
     "SetupPagesViewController": SetupPagesViewController.self, 
     "MainViewController": MainViewController.self 
    ] 

    let typeOfCtrl: Any.Type = Mirror(reflecting: ctrl).subjectType 
    if objectList[controllerIdentifier] == typeOfCtrl { 
     return ctrl as? UIViewController 
    } 

    return nil 
} 
1

您可以使用Objective-C運行時(由基金會暴露)的這種情況的內省機制,即對NSObjectisKindOfClass方法:

let checks: [String:AnyClass] = [ 
    "SetupPagesViewController": SetupPagesViewController.self, 
    "MainViewController": MainViewController.self, 
] 

if let clazz = checks[controllerIdentifier] where ctrl.isKindOfClass(clazz) { 
    return ctrl 
} 

請注意,這個工作,類必須從NSObject繼承。

0

如何:

typealias NSViewController = Any 

class A : NSViewController {} 
class B : NSViewController {} 
class C : NSViewController {} 

let classes : [AnyClass] = [ 
    A.self, 
    B.self, 
    C.self 
] 

func isValid(ctrl: NSViewController, controllerIdentifier: String) -> NSViewController? { 
    if classes.contains({ controllerIdentifier == String($0) && ctrl.dynamicType == $0 }) { 
     return ctrl 
    } else { 
     return nil 
    } 
} 

(該typealias只是簡化它,無所謂真的)。這適用於任何類型,您也不需要爲類提供名稱,因爲String(someClass)爲您提供了名稱。我在這裏使用了contains,因爲我認爲你只是想檢查它是否是一個有效的視圖控制器,如果它是返回的。