最近忽然發(fā)現(xiàn)了一個(gè)swift的之前發(fā)布的feature,很有意思,之后開發(fā)可能用得到,記錄一下。
@_dynamicReplacement(for:)
動(dòng)態(tài)方法替換,需要swift版本5.1以上,這東西貌似是為了實(shí)現(xiàn)Xcode中swiftUI的preview而加進(jìn)來的,不過既然加進(jìn)來了,就肯定可以用來做其他的,舉例如下。
class Person {
dynamic func say() {
print("hi")
}
}
extension Person {
@_dynamicReplacement(for: say)
func sayA() {
print("A1")
say()
print("A2")
}
}
Person().say()
// 輸出 A1 hi A2
注意事項(xiàng):
- 除非增加
-enable-implicit-dynamic的編譯標(biāo)志(building setting -> swift compiler - Custom Flags -> Other Swift Flags),否則,被替換的方法需要被dynamic標(biāo)記,不然無法通過編譯 - 在使用OC的運(yùn)行時(shí)方法替換時(shí),想要執(zhí)行原方法,應(yīng)該調(diào)用
sayA,但在使用@_dynamicReplacement時(shí),直接調(diào)用say就可以了
連環(huán)替換的場(chǎng)景
上面的情況看起來沒有什么特殊的,我們看一下連環(huán)替換的場(chǎng)景
class Person {
dynamic func say() {
print("hi")
}
}
extension Person {
@_dynamicReplacement(for: say)
func sayA() {
print("A1")
say()
print("A2")
}
}
extension Person {
@_dynamicReplacement(for: say)
func sayB() {
print("B1")
say()
print("B2")
}
}
Person().say()
如果是OC的運(yùn)行時(shí)實(shí)現(xiàn)方法替換,不難想象輸出會(huì)是:
B1 - A1 - hi - A2 - B2
但在這里,會(huì)輸出:
B1 - hi - B2
后聲明的方法替換才會(huì)生效,但假如我們添加-Xfrontend和-enable-dynamic-replacement-chaining這兩個(gè)編譯標(biāo)志后,就可以得到:
B1 - A1 - hi - A2 - B2
我這里只記錄一下,具體的原理和分析可以看下下面的參考鏈接。