美文网首页iOS Developer收藏ios
MethodSwizzle体现Swift与ObjC派发机制的区别

MethodSwizzle体现Swift与ObjC派发机制的区别

作者: 随风踏叶 | 来源:发表于2018-06-04 15:15 被阅读189次

    首先,实现一个swizzle方法替换People对象run()的IMP为runNew()的IMP,然后用两种方式调用run(),结果会是一样的吗?

    代码如下:

    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let peo = People()
    
            peo.run()
            peo.perform(#selector(People.run))
    
            self.swizzle()
    
            peo.run()
            peo.perform(#selector(People.run))
    
        }
    }
    
    extension ViewController {
    
        func swizzle() {
    
            let cls = People.self
            let orgSel = #selector(People.run)
            let newSel = #selector(runNew)
    
            if let newMethod = class_getInstanceMethod(ViewController.self, newSel) {
    
                let newImp = method_getImplementation(newMethod)
                let type = method_getTypeEncoding(newMethod)
    
                class_replaceMethod(cls, orgSel, newImp, type)
    
            }
        }
    
        @objc func runNew() {
            print("run new")
        }
    }
    
    @objc class People: NSObject {
        @objc func run() {
            print("run")
        }
    }
    

    直接贴出代码运行结果:

    run
    run
    run
    run new
    

    显然,都是调用run方法,两者结果是不一样的:
    peo.run() -- run
    peo.perform(#selector(People.run)) -- run new

    谜底是什么

    Swift的默认派发机制是直接派发(Direct Dispatch)
    这里是NSObject的子类,是函数表派发,
    ObjC的派发机制是消息机制派发(Message Dispatch),

    在Swift中,这里run()走的是直接派发函数表派发,而perform走的是消息机制派发。
    如果要更改run()的派发方式,可以在run()方法前面加上dynamic
    @objc dynamic func run(),这时调用run()走的是消息机制派发。

    再次运行:

    run
    run
    run new
    run new
    

    更新

    除了加上dynamic的方式,还可以用extension。extension NSObject子类的方法是消息机制派发。

    extension People {
        @objc func run() {
            print("run")
        }
    }
    

    参考

    深入理解 Swift 派发机制

    相关文章

      网友评论

        本文标题:MethodSwizzle体现Swift与ObjC派发机制的区别

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