【问题标题】:Method Swizzling - How to assure methods are swizzled before they are calledMethod Swizzling - 如何确保方法在被调用之前被 swizzled
【发布时间】:2011-01-13 00:22:19
【问题描述】:

我正在使用 SIMBL 调配第三方应用程序创建 NSMenuItems 的方法,但有 50/50 的时间菜单项是在我的方法调配被初始化之前创建的。

什么是确保我的调酒始终排在第一位的干净方法?我想我可以调配 applicationDidFinishLaunching: 并继续我的调配。但我担心我会在那里遇到同样的错误,在我的实际调酒到位之前会调用 applicationDidFinishLaunching。

约翰

【问题讨论】:

    标签: objective-c swizzling


    【解决方案1】:

    您希望在加载库后立即进行调配。您可以通过+initialize+load 或构造函数来实现。

    @bbum 的answer to this question 提供了更多信息,以及one of his blog posts 使用这些特殊类方法的注意事项。

    (我故意不质疑你所做的事情的智慧;))

    【讨论】:

    • 构造函数对我没有任何好处。构造函数中的代码在 +load 之后运行。所以一个后续问题是,我如何让我的 SIMBL 插件在应用程序 start 时注入自身,而不是延迟几秒钟?
    • 另外,我还可以通过哪些其他方式从 3rd 方应用程序访问 NSMenuItem,而无需对它们进行调配?我可以使用它们的类之一访问应用程序 applicationDockMenu: [[[[AppController sharedController] applicationDockMenu:nil] itemArray] objectAtIndex:0] 但是在创建菜单栏的类中没有共享控制器。
    【解决方案2】:

    你可以像这样使用构造函数:

    __attribute__((constructor)) static void do_the_swizzles()
    {
        // Do all your swizzling here.
    }
    

    来自GCC documentation

    constructor 属性导致函数被调用 执行前自动进入main()

    注意:虽然这最初来自GCC,但它也适用于LLVM

    【讨论】:

    • 使用 +load Objective-C 方法可能是一个更好的主意,因为它在 C/C++ 构造函数之前处理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多