1

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. Is there a way I can have it fire in both?

4

1 回答 1

3

在调配方法时,您基本上是在告诉 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:]最终会调用你的 swizzled 方法的原因。

整齐吧?

于 2016-03-03T23:44:09.930 回答