Method swizzling on NSObject, does not work with UIView

264 Views Asked by At

Yet another method swizzling question, not asked before.

I'd like to monitor all release calls in my application, thus I decided to use method swizzling, on NSObject, so that it would be possible to monitor of all classes. The actual code has been taken from here, but I'll also append it here for clarity.

It seems that, although all (most?) of the cases work, this doesn't work for UIView and its children.

I was expecting that, even if UIView overrides this method, or even if swizzles it, at the end of the day this method will end up at the original release method, thus through swizzling my code will be executed.

If I put swizzling on the UIView class and on the NSObject class, then swizzling works perfect. Also Swizzling works fine in UIResponder classes if I put it on NSOBject. It seems that UIView has some kinf of custom implementation that breaks the chain?

Here is the code I am using:

#import <objc/runtime.h>
#import <UIKit/UIKit.h>

@implementation NSObject (SwizzleRelease)

- (void)xxx_release {
    printf("Will release %s #%d\n", [NSStringFromClass([self class]) UTF8String], [self retainCount]);
    [self xxx_release];
}

+ (void)load {
    NSLog(@"LOADED");
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];

        SEL originalSelector = @selector(release);
        SEL swizzledSelector = @selector(xxx_release);

        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
        BOOL didAddMethod =
        class_addMethod(class,
                        originalSelector,
                        method_getImplementation(swizzledMethod),
                        method_getTypeEncoding(swizzledMethod));

        if (didAddMethod) {
            class_replaceMethod(class,
                                swizzledSelector,
                                method_getImplementation(originalMethod),
                                method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

@end
0

There are 0 best solutions below