我遵循"This"指南。捕获UIView
touchesBegan,但是当我在UIViewController
中NSLog()
touchesBegan时,它不会着火,而是在swizzledmethod中着火。有没有办法让它两面都着火?
当swizzling方法时,你基本上是告诉Objective-C运行时改变它的内部映射的方法选择器(你如何调用它)到一个方法实现(当它被调用时它做什么)。要意识到的关键是,这些在Objective-C中实际上是不同的(尽管我们在编码时通常不会考虑这个区别)。如果你能理解选择器映射的概念,理解swizzling就很容易了。
典型的模式是将现有的方法(通常是你不控制的类)与你自己的自定义方法交换,通过交换它们的选择器,使你的选择器指向现有的实现,现有的选择器指向你的实现。
这样做之后,你可以通过调用自定义方法的选择器来调用原始的实现。
对于外部观察者来说,这似乎创建了一个重入循环:
- (void)swizzled_touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// custom logic
[self swizzled_touchesBegan:touches withEvent:event]; // <-- this actually calls the original implementation
// custom logic
}
…但是因为您交换了选择器,所以看起来递归的选择器实际上指向原始实现。这就是为什么调用[view touchesBegan: withEvent:]
最终会调用swizzzed方法的原因。
整洁吗?