繁体   English   中英

在 Swift 2 中动态检查对象类型

[英]Dynamically check an object type in Swift 2

我正在构建 iOS 应用程序的状态恢复。 我目前有

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重用它。

那可能吗? 如何? 谢谢

为此,您可以使用 Objective-C 运行时的自省设施(由 Foundation 公开),即NSObjectisKindOfClass方法:

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

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

请注意,要使其正常工作,类必须从NSObject继承。

这个怎么样:

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
    }
}

(类型别名只是为了简化它,实际上并不重要)。 这适用于任何类型,您也不需要为类提供名称,因为String(someClass)为您提供了名称。 我在这里使用contains是因为我认为您只想检查它是否是有效的视图控制器,如果是,则返回。

认为这种 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
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM