美文网首页
Swift 3.x Method Swizzling

Swift 3.x Method Swizzling

作者: sun5kong | 来源:发表于2017-08-25 14:31 被阅读149次

    在Swift3.x版本当你调用initialize()会出现下图警告:

    屏幕快照 2017-08-25 下午12.12.02.png

    大致的意思是initialize()该方法将会被删除.

    参考国外的大牛方法的实现方式:

    解决思路: initialize()是提供一个runtime代码的插入位置, 且这个方法只能执行一次, 我们在程序刚执行的时候调用runtime获取所有的class, 然后遍历它们, 如果class实现了protocol的代理就立即执行代理的方法.

    • 第一步
    protocol SelfAware: class {
        static func awake()
    }
    
    class NothingToSeeHere {
        static func harmlessFunction() {
            /*
             *  public func objc_getClassList(_ buffer: AutoreleasingUnsafeMutablePointer<Swift.AnyClass?>!, _ bufferCount: Int32) -> Int32
             *  该函数是获取已注册的类, 传入两个参数
             *  第一个参数buffer: 已分配好空间的数组
             *  第二个参数bufferCount: 数组中存放元素的个数
             *  返回值是注册的类的总数
             *  当参数bufferCount的值小于注册类的总数, 获取到的注册类的集合的任意子集
             *  第一个参数为nil时将会获取到当前注册的所有的类, 此时可存放元素的个数为0, 返回自为当前所有类的总数
             */
            let typeCount = Int(objc_getClassList(nil, 0))
            //存放class的已分配好的空间的数组指针
            let types = UnsafeMutablePointer<AnyClass?>.allocate(capacity: typeCount)
            //存放class的已分配好的空间的可选数组指针
            let autoreleasingTypes = AutoreleasingUnsafeMutablePointer<AnyClass?>(types)
            //获取已注册的类存放到types里
            objc_getClassList(autoreleasingTypes, Int32(typeCount))
            for index in 0..<typeCount {
                //实现SelfAware协议, 会执行方法
                (types[index] as? SelfAware.Type)?.awake()
            }
            types.deallocate(capacity: typeCount)
        }
    }
    
    • 第二部
    extension UIApplication {
        private static let runOnce: Void = {
            NothingToSeeHere.harmlessFunction()
        }()
        
        open override var next: UIResponder? {
            UIApplication.runOnce
            return super.next
        }
        
    }
    
    • 第三部
    class ViewController: UIViewController, SelfAware {
    
        static func awake() {
            print("1111111111")
        }
        
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
    
    }
    

    相关文章

      网友评论

          本文标题:Swift 3.x Method Swizzling

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