美文网首页iOS日常积累
swift 方法替换swizzing

swift 方法替换swizzing

作者: 蔡胜波 | 来源:发表于2023-05-30 15:00 被阅读0次

    最近忽然发现了一个swift的之前发布的feature,很有意思,之后开发可能用得到,记录一下。

    @_dynamicReplacement(for:)

    动态方法替换,需要swift版本5.1以上,这东西貌似是为了实现Xcode中swiftUI的preview而加进来的,不过既然加进来了,就肯定可以用来做其他的,举例如下。

    class Person {
        dynamic func say() {
            print("hi")
        }
    }
    
    extension Person {
        @_dynamicReplacement(for: say)
        func sayA() {
            print("A1")
            say()
            print("A2")
        }
    }
    
    Person().say()
    // 输出 A1   hi   A2
    

    注意事项:

    1. 除非增加-enable-implicit-dynamic的编译标志(building setting -> swift compiler - Custom Flags -> Other Swift Flags),否则,被替换的方法需要被 dynamic 标记,不然无法通过编译
    2. 在使用OC的运行时方法替换时,想要执行原方法,应该调用sayA,但在使用@_dynamicReplacement时,直接调用say就可以了

    连环替换的场景

    上面的情况看起来没有什么特殊的,我们看一下连环替换的场景

    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的运行时实现方法替换,不难想象输出会是:
    B1 - A1 - hi - A2 - B2
    但在这里,会输出:
    B1 - hi - B2
    后声明的方法替换才会生效,但假如我们添加-Xfrontend-enable-dynamic-replacement-chaining这两个编译标志后,就可以得到:
    B1 - A1 - hi - A2 - B2

    我这里只记录一下,具体的原理和分析可以看下下面的参考链接。

    参考

    1. https://www.guardsquare.com/blog/swift-native-method-swizzling
    2. https://www.desgard.com/ios/swift/2019/07/27/swift-method-swizzling.html

    相关文章

      网友评论

        本文标题:swift 方法替换swizzing

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