ios - Objective-C 为对象的每个方法添加功能

标签 ios objective-c cocoa

我想为 objective-c 中的对象构建一个小型插件系统。

现在我想动态地(在运行时)向对象中的每个可用函数添加一行代码。

我试过运行时库,但还没有找到解决方案。

到目前为止我尝试过的是:

        id (^impyBlock)(id, id, ... ) = ^(id self_, id arguments, ...)
        {
            // My custom code for every function here
            id (*func)(__strong id,SEL,...) = (id (*)(__strong id, SEL, ...))imp;
            return func(obj, s, arguments);

        };

        id (*impyFunct)(id, SEL,...) = imp_implementationWithBlock(impyBlock);
        method_setImplementation(mList[i], impyFunct);

我的问题是,当有多个参数时,我没有机会将它们传递给“func()”。据我所知,这在 C 中是不可能的。

我想到的另一个解决方案是使用方法调配来施展魔法。

步骤:

  1. 创建一个“swizzle 方法”,它只调用我的自定义代码,然后调用原始方法(通过命名模式)
  2. 使用“swizzle 方法”之一更改每个函数的 IMP
  3. 使用“旧”实现创建一个新方法并将名称更改为类似于“___name”的模式

在这个解决方案中,我卡在了第 3 点。我还没有设法动态创建一个完整的新方法。

有没有人可以帮助我解决上述问题,或者有其他解决方案来实现“捕获所有方法功能”。

最好的是像 forwardInvocation 这样的东西,它也可以捕获已经定义的函数。

感谢您的帮助!

最佳答案

让我把它分成两部分,因为我无法理解你的两个问题之间的联系。

我。使用“旧”实现创建一个新方法并将名称更改为类似“___name”的模式

这很简单,尽管我不明白这将如何解决您的问题。您仍然不能将可变参数函数参数传递给这样的方法(您是对的,这不能在 C 中完成)。

IMP swapImpForSelector(Class cls, SEL sel, IMP newImp)
{
    Method m = class_getInstanceMethod(cls, sel);
    IMP oldImp = method_setImplementation(m, newImp);

    NSString *newSel = [NSString stringWithFormat:@"__prefixed_%@", NSStringFromSelector(sel)];
    const char *type = method_getTypeEncoding(m);
    class_addMethod(cls, NSSelectorFromString(newSel), oldImp, type);

    return oldImp;
}

二。如果你想在函数之间传递可变参数,你可能需要退回到大量的汇编黑客攻击。幸运的是,一些聪明人已经为您做到了。

要么使用 NSInvocation class ,或者如果还不够,则 libffi甚至更低。

关于ios - Objective-C 为对象的每个方法添加功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17116855/

相关文章:

ios - LongpressGesture 结束不会关闭 View

iphone - 以编程方式获取设备的电话号码

objective-c - 从窗口坐标转换 NSPoint

iphone - 对齐 UITableView 的页脚中的文本

objective-c - OSX - 如何获取 NSTask 的内存使用情况?

objective-c - 快速发布

ios - ios 上的溢出菜单类似于 android

ios - InteractivePopGestureRecognizer 弹出太多 View

ios - iOS 应用程序崩溃 : ZL36GetSFTrimCharSetForChineseOrJapanesePPK9TFontInfo_block_invoke

objective-c - 当我尝试使用两个 CIFilter 时出现一些问题