【问题标题】:swift method_exchangeImplementations not workswift method_exchangeImplementations 不起作用
【发布时间】:2016-01-19 08:33:03
【问题描述】:

swift代码如下:

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方法体,所以我认为它交换失败了,这两个方法在同一个类中,有人知道为什么吗?

【问题讨论】:

  • 它对我有用。结果是function1 log function2 log。我正在使用 Xcode 7.2。
  • 真的吗?我的还是不行

标签: swift objective-c-runtime


【解决方案1】:

我明白了,在方法名前加上“动态”关键字!!!
像这样:

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

}

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

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

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

【讨论】:

    猜你喜欢
    • 2016-08-26
    • 2014-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多