简体   繁体   English

为UIView调整方法

[英]Method Swizzling for UIView

I am following " This " guide. 我正在关注“ 这个 ”指南。 to capture UIView touchesBegan, but when I NSLog() touchesBegan in the UIViewController that this is for, it doesn't fire but does fire in the swizzled method. 捕获UIView touchesBegan,但是当我在UIViewController中使用NSLog() touchesBegan时,它不会触发,但会在swizzled方法中触发。 Is there a way I can have it fire in both? 有没有办法可以在两者中解雇它?

When swizzling methods, you are basically telling the Objective-C runtime to change its internal mapping of a method selector (how you call it) to a method implementation (what it does when called). 当调整方法时,您基本上是在告诉Objective-C运行时将方法选择器的内部映射(如何调用它)更改为方法实现 (调用时它的作用)。 The key thing to realize is that these are actually not the same thing in Objective-C (though we usually don't think about this distinction when coding). 要实现的关键是这些在Objective-C中实际上并不相同(尽管我们通常在编码时不考虑这种区别)。 If you can understand the concept of selector mapping, understanding swizzling is easy. 如果你能理解选择器映射的概念,那么理解混合​​很容易。

The typical pattern is to swap an existing method (usually of a class you don't control) with your own custom method of the same signature by exchanging their selectors so that your selector points to the existing implementation and the existing selector points to your implementation. 典型的模式是通过交换选择器将现有方法(通常是您无法控制的类)与您自己的相同签名的自定义方法交换,以便您的选择器指向现有实现,现有选择器指向您的实现。

Having done this, you can actually call the original implementation by calling your custom method's selector. 完成此操作后,您可以通过调用自定义方法的选择器来实际调用原始实现。

To an outside observer this appears to create a re-entrancy loop: 对于外部观察者来说,这似乎创建了一个重新进入循环:

- (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
}

…but because you have swapped the selectors, the selector that appears to recurse actually points to the original implementation. ...但是因为你已经交换了选择器,看起来recurse的选择器实际上指向了原始实现。 This is exactly why calling [view touchesBegan: withEvent:] ends up calling your swizzled method in the first place. 这正是为什么调用[view touchesBegan: withEvent:]最终会调用你的混合方法。

Neat eh? 整洁啊?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM