简体   繁体   中英

Is Method swizzling in a static library possible?

I'm trying to create an automatic UI logging and I found method swizzling as a really nice solution to the problem. I've tried to swizzle the sendAction method of the UIApplication implementation.

My issue is that sometimes it works and sometimes it doesn't. Especially if I write the code in a static library, export it to an .a file and use it in my project.

  1. should method swizzling be a problem if its implemented within a static library?

  2. even in code, it sometimes work and sometimes nothing happens. It always go into the load method but not always into the heap_sendAction method.

Here is the code:

#import <objc/runtime.h>

@implementation UIApplication (EventAutomator)

+ (void)load 
{
    Class class = [self class];
    SEL originalSelector = @selector(sendAction:to:from:forEvent:);
    SEL replacementSelector = @selector(heap_sendAction:to:from:forEvent:);

    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    Method replacementMethod = class_getInstanceMethod(class, replacementSelector);
    method_exchangeImplementations(originalMethod, replacementMethod);
}

- (BOOL)heap_sendAction:(SEL)action to:(id)target from:(id)sender forEvent:(UIEvent *)event 
{
    NSString *selectorName = NSStringFromSelector(action);
    printf("Selector %s occurred.\n", [selectorName UTF8String]);
    return [self heap_sendAction:action to:target from:sender forEvent:event];
}

@end

----- UPDATE ---- :

heap_sendAction is called when i place the function inside a viewcontroller.m class. I'm trying different code locations now to see when it works and when it doesnt.

From Apple documentation regarding load method :

The load message is sent to classes and categories that are both dynamically loaded and statically linked, but only if the newly loaded class or category implements a method that can respond.

The order of initialization is as follows:

  1. All initializers in any framework you link to.

  2. All +load methods in your image.

  3. All C++ static initializers and C/C++ attribute (constructor) functions in your image.

  4. All initializers in frameworks that link to you.

In addition:

  • A class's +load method is called after all of its superclasses' +load methods.

  • A category +load method is called after the class's own +load method.

So, method swizzling is not a problem, even in static library, because classes from frameworks you link to already loaded at this point. method_exchangeImplementations should work as expected. Looks like problem is somewhere else.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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