Objective c 中方法调配和类别之间的区别
Difference between method swizzling and category in Objective c
我只是了解在 obj c 中完成的方法调配 Method Swizzling and dangers of using method swizzling 并且忍不住在进行方法调配和使用类别覆盖方法实现之间进行比较。
它们都有助于覆盖预定义框架方法的功能。
那么两者有什么区别或者可以互换使用吗?
主要区别在于 Objective C 阻止您从类别覆盖中调用原始实现。这是因为 Objective-C 的 super
调用从超级 class 开始,而类别覆盖相同 class 级别的方法。
另一方面,方法调配让您也可以保留对原始实现的引用,以便您可以从您的实现内部调用它。例如,在您的第一篇 link 文章中,作者是这样写的:
- (void) logged_viewDidAppear:(BOOL)animated {
[self logged_viewDidAppear:animated];
NSLog(@"logged view did appear for %@", [self class]);
}
第二行调用了 logged_viewDidAppear:
方法,这看起来像是对自身的无条件调用,应该会导致无限递归。然而,事实并非如此:在调配之后,由于方法调配的工作方式,此调用被转换为对原始 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
}
}
类别或扩展可让您执行以下操作:
添加计算属性和计算类型属性
定义实例方法和类型方法
提供新的初始值设定项
定义下标
定义和使用新的嵌套类型
使现有类型符合协议
(来自苹果)
他们不允许您扩展您正在扩展的相同 class 的原始方法,如果您像上面的代码那样尝试,则会弹出方法签名冲突。
您可能想查看此网站以图表方式了解概念。我真的很喜欢它。
http://matteogobbi.github.io/blog/2014/12/15/extending-methods-in-a-category-by-method-swizzling/
确保查看这篇很棒的文章以获得良好的实现细节:
http://nshipster.com/method-swizzling/
我只是了解在 obj c 中完成的方法调配 Method Swizzling and dangers of using method swizzling 并且忍不住在进行方法调配和使用类别覆盖方法实现之间进行比较。 它们都有助于覆盖预定义框架方法的功能。 那么两者有什么区别或者可以互换使用吗?
主要区别在于 Objective C 阻止您从类别覆盖中调用原始实现。这是因为 Objective-C 的 super
调用从超级 class 开始,而类别覆盖相同 class 级别的方法。
另一方面,方法调配让您也可以保留对原始实现的引用,以便您可以从您的实现内部调用它。例如,在您的第一篇 link 文章中,作者是这样写的:
- (void) logged_viewDidAppear:(BOOL)animated {
[self logged_viewDidAppear:animated];
NSLog(@"logged view did appear for %@", [self class]);
}
第二行调用了 logged_viewDidAppear:
方法,这看起来像是对自身的无条件调用,应该会导致无限递归。然而,事实并非如此:在调配之后,由于方法调配的工作方式,此调用被转换为对原始 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
}
}
类别或扩展可让您执行以下操作: 添加计算属性和计算类型属性
定义实例方法和类型方法
提供新的初始值设定项
定义下标
定义和使用新的嵌套类型
使现有类型符合协议
(来自苹果)
他们不允许您扩展您正在扩展的相同 class 的原始方法,如果您像上面的代码那样尝试,则会弹出方法签名冲突。
您可能想查看此网站以图表方式了解概念。我真的很喜欢它。
http://matteogobbi.github.io/blog/2014/12/15/extending-methods-in-a-category-by-method-swizzling/
确保查看这篇很棒的文章以获得良好的实现细节: http://nshipster.com/method-swizzling/