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
同时修饰后, 会变成消息调度 -
@_dynamicReplacement
Swift 5 Method Swizzling
被@_dynamicReplacement(for: 方法)
修饰方法, 参数for:
后面就是将被替换的方法
即调用方法
时会调用被@_dynamicReplacement(for: 方法)
修饰的方法注:
@_dynamicReplacement
关键字需要使用在extension
中e.g.
@_dynamicReplacement
class Person { dynamic func speechChinese() { print("speechChinese") } } extension Person { @_dynamicReplacement(for: speechChinese()) func speechEnglish() { print("speechEnglish") } } let p = Person() p.speechChinese() // 此时会调用 speechEnglish()