final、dynamic、objc和_dynamicReplacement - ShenYj/ShenYj.github.io GitHub Wiki
-
static被
static修饰后,类型方法采用静态调度 -
final-
final修饰符只能修饰类,不能修饰结构体和枚举,表明该类不能被其他类继承,也就是它没资格当父类 -
final修饰符也可以修饰类中的属性、方法和下标,但前提是该类并没有被final修饰过 -
final修饰方法后,将原有的sil-vtable函数表调度变为静态调用(直接调用)
-
-
@objc标记暴露给
Object-C, 不会修改方法的调度方式, 仍表调度 (前提是在类主体中,若在extension中会改为消息调度)-
对编译器来说被修饰的方法会生成两个方法, 一个默认存在
Swift类的方法表中, 另一个暴露给Object-C使用- 在
Object-C调用方法时, 会再调用swift定义的原有的方法
- 在
-
@objc修饰后, 就可以通过runtime API获取对应的信息了, 如方法列表, 但如果需要给Object-C使用, 还需要继承自NSObject,两个条件缺一不可
-
-
dynamic被
dynamic修饰的方法有了动态特性, 依旧是表调度允许被交换调用(
@_dynamicReplacement(for: 方法名)), 类似于Object-C的运行时方法动态交换 -
@objc dynamic被
@objc dynamic同时修饰后, 会变成消息调度 -
@_dynamicReplacementSwift 5 Method Swizzling被@_dynamicReplacement(for: 方法)修饰方法, 参数for:后面就是将被替换的方法
即调用方法时会调用被@_dynamicReplacement(for: 方法)修饰的方法注:
@_dynamicReplacement关键字需要使用在extension中e.g.
@_dynamicReplacementclass Person { dynamic func speechChinese() { print("speechChinese") } } extension Person { @_dynamicReplacement(for: speechChinese()) func speechEnglish() { print("speechEnglish") } } let p = Person() p.speechChinese() // 此时会调用 speechEnglish()