type
status
date
slug
summary
tags
category
icon
password
我们看以下一个例子,我们在 MyController 中交换 LoadView 和 myLoadView 方法
我们没有在 myLoadView 上使用 dynamic 修饰,交换方法失败,并且系统会在 myLoadView 方法中第二行调用 myLoadView 时提示:函数调用导致无限递归
notion image
原因,此时方法派发方式为遍历 VTable 表查找方法,详情参考
我们只使用 @objc 对方法进行了修饰,没有使用 dynamic,所以方法系统在这里只是额外生成了一个 @objc MyController.myLoadView 函数,并没有对方法进行动态派发,所以交换方法不成功
此时我们运行程序,得到递归的结果,无限打印 “交换了 loadView 方法”
notion image
此时我们加上 dynamic 字段
警告消失,方法交换成功,程序正常运行
notion image
如果我们将 myLoadView 方法移动到 extension 中
加入 dynamic 没有影响,运行结果正常,方法交换成功
notion image
当我们在 extension 中去掉 dynamic,运行结果依然正常,方法交换成功
notion image
得出结论:在 extension 中加上 @objc 修饰方法,就是直接动态派发了
我们知道 KVO 是基于 MethodSwizzling 实现的,所以在 Swift 中 KVO 同样适用于上述逻辑
Swift 的消息派发KVOOC 的消息转发