【发布时间】:2015-06-07 16:32:26
【问题描述】:
我只是了解在 obj c Method Swizzling 和 dangers of using method swizzling 中完成的方法调配,并忍不住在使用类别进行方法调配和覆盖方法实现之间进行了比较。 它们都有助于覆盖预定义框架方法的功能。 那么这两者有什么区别还是可以互换使用呢?
【问题讨论】:
标签: ios objective-c swizzling
我只是了解在 obj c Method Swizzling 和 dangers of using method swizzling 中完成的方法调配,并忍不住在使用类别进行方法调配和覆盖方法实现之间进行了比较。 它们都有助于覆盖预定义框架方法的功能。 那么这两者有什么区别还是可以互换使用呢?
【问题讨论】:
标签: ios objective-c swizzling
主要区别在于,Objective C 阻止您从类别覆盖调用原始实现。这是因为 Objective-C 的 super 调用从超类开始,而类别覆盖同一类级别的方法。
另一方面,方法调配允许您保留对原始实现的引用,以便您可以从实现内部调用它。例如,在您第一个链接的文章中,作者写道:
- (void) logged_viewDidAppear:(BOOL)animated {
[self logged_viewDidAppear:animated];
NSLog(@"logged view did appear for %@", [self class]);
}
第二行调用logged_viewDidAppear: 方法,这看起来像是对自身的无条件调用,应该会导致无限递归。然而,这不是发生的事情:在 swizzling 之后,由于方法 swizzling 的工作方式,这个调用被转换为对原始 viewDidAppear: 的调用。
相比之下,从类别中覆盖方法不会让您访问要覆盖的方法的逻辑。它允许您替换逻辑,但不允许您扩展它。
【讨论】:
extension UIViewController{
public func myViewDidLoad(){
self.viewDidLoad()
//but you need to call this method everywhere replacing
}
//you cant do this
public func viewDidLoad(){
self.viewDidLoad()
//my code
}
}
类别或扩展可让您执行以下操作: 添加计算属性和计算类型属性
定义实例方法和类型方法
提供新的初始化器
定义下标
定义和使用新的嵌套类型
使现有类型符合协议
(来自苹果)
他们不允许你扩展你正在扩展的同一个类的原始方法,如果你尝试像上面的代码方法签名冲突弹出。
您可能需要查看此网站以图解方式了解该概念。我真的很喜欢它。
http://matteogobbi.github.io/blog/2014/12/15/extending-methods-in-a-category-by-method-swizzling/
请务必查看这篇很棒的文章以获得良好的实现细节: http://nshipster.com/method-swizzling/
【讨论】: