2016-01-19 49 views
4

SWIFT代码如下:迅速method_exchangeImplementations不行

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 

///// 我的环境中迅速以项目为基础,xcode7.2
这始终运行进入funtion1方法体,所以我认为它交换失败了,这两个方法是在同一个类中,有谁知道为什么?

+0

这对我的作品。结果是'function1 log function2 log'。我正在使用Xcode 7.2。 – t4nhpt

+0

真的吗,我的还不能 – Tornado

回答

4

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

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

} 

原因:
夫特优化代码来调用,而不是仰视在运行该方法的位置作为在Objective-C直接存储器地址。所以我们需要告诉代码运行它作为Objective-C代码。

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

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