美文网首页iOS-swift
二十一、Swift3.0之反射机制和命名空间

二十一、Swift3.0之反射机制和命名空间

作者: ZhengYaWei | 来源:发表于2017-03-01 21:06 被阅读1634次

    反射机制:
    对于任意一个类,都能够知道这个类的属性和方法;对于任意一个对象,都能够调用它的任意一本方法和属性。这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

    在OC中的反射机制:
    NSClassFromString
    isKindOfClass
    isMemberOfClass
    responsesToSelector
    performSelector或objc_msgSend间接调用方法

    反射机制的利用:
    团队开发中,A开发一个类,B开发一个类,但是A想使用B的东西,但是B还没写好,这时A就可以通过使用NSClassFromString,减少对B开发代码的依赖性

    反射机制的实际应用:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
            /*
             代码中的?都是可选解包,发送消息,不参与计算
             所有的?都是Xcode自动生成的
             */
            window = UIWindow()
            window?.backgroundColor = UIColor.white
            
            //设置跟控制器要添加命名空间(默认是项目名称,最好不要有特殊符号)
            //        let vc = ViewController()
            let clsName = "反射机制.ViewController"
            let cls = NSClassFromString(clsName) as? UIViewController.Type
            //使用类来创建视图控制器
            let vc = cls?.init()
            
            window?.rootViewController = vc
            window?.makeKeyAndVisible()
            return true
        }
    

    从info.plist中抽取命名空间

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
            window = UIWindow()
            window?.backgroundColor = UIColor.white
            //因为字典是可选的,因此需要解包再取值,如果字典为nil就不取值
            //通过key从子点中取值,如果key错了,就没有值了
            let ns = Bundle.main.infoDictionary?["CFBundleName"] as? String ?? ""
            let clsName = ns+"."+"ViewController"
            let cls = NSClassFromString(clsName) as? UIViewController.Type
            //使用类来创建视图控制器
            let vc = cls?.init()
            
            window?.rootViewController = vc
            window?.makeKeyAndVisible()
            return true
        }
    

    抽取nameSpace的计算型属性

    extension Bundle{
        //返回命名空间字符串
    //    func nameSpace() -> String {
    //        return Bundle.main.infoDictionary?["CFBundleName"] as? String ?? ""
    //    }
        
        //计算型属性
        var nameSpace: String{
            return Bundle.main.infoDictionary?["CFBundleName"] as? String ?? ""
        }
    }
    
     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
            window = UIWindow()
            window?.backgroundColor = UIColor.white
            //利用方法
            //let ns = Bundle.main.nameSpace()
            //利用计算型属性
            let ns = Bundle.main.nameSpace
            let clsName = ns+"."+"ViewController"
            let cls = NSClassFromString(clsName) as? UIViewController.Type
            //使用类来创建视图控制器
            let vc = cls?.init()
            window?.rootViewController = vc
            window?.makeKeyAndVisible()
            return true
        }
    

    总结:
    1、知道Swift中有命名空间
    -在同一个命名空间下,全局共享
    -第三方框架使用Swift,如果直接拖拽到项目中,就从属于同一个命名空间,很可能会冲突
    -以后要尽量使用Cocoapod
    2、重点要知道Swift中NSClassFromString(反射机制)的写法
    - 反射机制的最重要目的是为了解耦
    - 提示:反射机制和工厂方法,第一印象会发现一个简单的功能,写的会很复杂。但是封装的很好,而且弹性很大。

    相关文章

      网友评论

        本文标题:二十一、Swift3.0之反射机制和命名空间

        本文链接:https://www.haomeiwen.com/subject/qbpcgttx.html