swift method_exchangeImplementations不起作用

时间:2016-01-19 08:33:03

标签: swift objective-c-runtime

快速代码如下:

func swizzleMethod()
{
    let method:Method = class_getInstanceMethod(object_getClass(self), Selector("function1"))

    self.function1()
    let swizzledMethod:Method = class_getInstanceMethod(object_getClass(self), Selector("function2"))

    method_exchangeImplementations(method, swizzledMethod)

    self.function1()


}

func function1()
{
    print("function1 log")
}
func function2()
{
    print("function2 log")

}

记录:

function1 log

function1 log

///// 我的环境是基于swift的项目,xcode7.2
这总是遇到funtion1方法体,所以我认为它交换失败了,这两个方法在同一个类中,有谁知道为什么?

1 个答案:

答案 0 :(得分:4)

我得到答案,在方法名称前添加“dynamic”关键字!!!
像这样:

dynamic  func function1()
{
    print("function1 log")
}
dynamic func function2()
{
    print("function2 log")

}

原因:
Swift优化代码以调用直接内存地址,而不是像在Objective-C中那样在运行时查找方法位置。所以我们需要告诉代码运行将其视为Objective-C代码。

答案详情:
方法调配是一种将一种方法实现替换为另一种方法的技术。如果您不熟悉调配,请查看此博客文章。 Swift优化代码以调用直接内存地址,而不是像在Objective-C中那样在运行时查找方法位置。所以默认情况下,swizzling在Swift类中不起作用,除非我们:
1.使用dynamic关键字禁用此优化。如果代码库完全在Swift中,这是首选,也是最有意义的选择 2.扩展NSObject。不要只为方法调配这样做(使用动态代替)。知道方法调配将在已经存在的以NSObject作为基类的类中工作是有用的,但我们最好选择性地选择具有动态的方法。
3.对正在调整的方法使用@objc注释。如果我们想要调整的方法也需要同时暴露给Objective-C代码,这是合适的。

感谢文章:15 Tips to Become a Better Swift Developer