1

我正在尝试创建一个自动 UI 日志记录,我发现方法 swizzling 是解决该问题的一个非常好的解决方案。我试图调整实现的sendAction方法UIApplication

我的问题是有时有效,有时无效。特别是如果我在静态库中编写代码,将其导出到 .a 文件并在我的项目中使用它。

  1. 如果方法调配是在静态库中实现的,它应该是一个问题吗?

  2. 即使在代码中,它有时也可以工作,有时什么也没有发生。它总是进入load方法,但并不总是进入heap_sendAction方法。

这是代码:

#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

- - - 更新 - - :

当我将函数放在 viewcontroller.m 类中时,会调用 heap_sendAction。我现在正在尝试不同的代码位置,看看它何时有效,何时无效。

4

1 回答 1

0

Apple 文档中关于load方法

加载消息被发送到动态加载和静态链接的类和类别,但前提是新加载的类或类别实现了可以响应的方法。

初始化顺序如下:

  1. 您链接到的任何框架中的所有初始化程序。

  2. 图像中的所有 +load 方法。

  3. 映像中的所有 C++ 静态初始化程序和 C/C++属性(构造函数)函数。

  4. 链接到您的框架中的所有初始化程序。

此外:

  • 一个类的 +load 方法在其所有超类的 +load 方法之后被调用。

  • 在类自己的 +load 方法之后调用类别 +load 方法。

因此,即使在静态库中,方法调配也不是问题,因为此时您链接到的框架中的类已经加载。method_exchangeImplementations应该按预期工作。看起来问题出在其他地方。

于 2016-03-07T13:22:19.947 回答