问题
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?
回答1:
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). 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). 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. This is exactly why calling [view touchesBegan: withEvent:]
ends up calling your swizzled method in the first place.
Neat eh?
来源:https://stackoverflow.com/questions/23746685/method-swizzling-for-uiview