美文网首页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派发机制的区别

    首先,实现一个swizzle方法替换People对象run()的IMP为runNew()的IMP,然后用两种方式调...

  • Swift派发机制

    Swift之所以速度比Object-c快,我觉得跟他的派发机制有关。下面我们聊聊Swift的派发机制。 派发机制分...

  • 浅谈Swift派发机制

    函数的派发机制分为:静态派发(直接派发)、函数表派发、消息派发 1、Swift中所有ValueType(值类型:S...

  • iOS知识复习笔记(16)---swift相关

    一、函数的派发方式 swift函数的派发机制有三类:static直接派发(静态)派发、table函数派发,mess...

  • Swift派发机制

    Swift派发分:静态派发和动态派发 静态派发:(又叫:直接调用) 静态派发机制,同时支持值类型和引用类型;静态派...

  • Swift的函数派发

    前言 对于Swift的学者来说函数派发有很大的误区:就是认为Swift沿用Objective-C的消息派发机制,且...

  • 注意NSObject被回收

    本人新手一个,对于objc以及swift与objc的混用完全不懂。但是对于swift对象的回收机制还是略知一二的。...

  • Swift - 三种函数派发

    Swift 的函数派发可以分为 静态 和 动态 两种机制,而动态派发又分为 函数表派发 和 消息派发 。 Swif...

  • Swift 派发机制

    此篇博客用来自我学习,来源戴铭大佬的这篇博客 Swift 派发机制 派发目的是让 CPU 知道被调用的函数在哪里。...

  • Swift 派发机制

    表格总结如下: 值类型使用直接派发 协议、类的初始化声明使用函数表派发 协议、类的 extension 使用直接派...

网友评论

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

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