【问题标题】:Adding Objective-C method to class at runtime在运行时向类添加 Objective-C 方法
【发布时间】:2013-12-23 01:16:08
【问题描述】:

我正在尝试在旧系统上支持 10.9 中新添加的 NSColor 方法。在 10.9 之前,我将这些放在一个允许我在 Mac 和 iOS 之间统一代码的类别中。现在 10.9 有这些方法,无论我在哪里使用它们,我都会得到奇怪的绘图。我想将这些方法动态地添加到较旧的运行时中,并且我找到了一些关于如何使用 class_addMethod 进行操作的参考资料。问题是,即使 addMethod 返回成功,也不会调用方法。

NSColor *
fColorWithWhite(id self, SEL _cmd, float white, float alpha) {
    return [NSColor colorWithDeviceWhite: white
                                   alpha: alpha];
}

NSColor *
fColorWithRedGreenBlue(id self, SEL _cmd, float red, float green, float blue, float alpha) {
    return [NSColor colorWithDeviceRed: red
                                 green: green
                                  blue: blue
                                 alpha: alpha];
}

+ (void)addLegacySupport {
    Class class = NSClassFromString(@"NSColor");

    BOOL success = class_addMethod(class, @selector(colorWithWhite:alpha:), (IMP)fColorWithWhite, "@@:ff");
    NSLog(@"colorWithWhite:alpha: - %i", success);

    success = class_addMethod(class, @selector(colorWithRed:green:blue:alpha:), (IMP)fColorWithRedGreenBlue, "@@:ffff");
    NSLog(@"colorWithRed:green:blue:alpha: - %i", success);
}

任何指针将不胜感激。

【问题讨论】:

    标签: objective-c


    【解决方案1】:

    您正在尝试添加类方法。您需要将它们添加到元类中。

    Class meta_cls = objc_getMetaClass("NSColor");
    

    【讨论】:

    • 这看起来太棒了,我简直不敢相信我没有在 API 文档中看到它,而且在 class_addMethod 上也返回了 false。
    • 已解决:上述方法有效。根本问题与将 double 转换为 CGFloat 转换为浮点有关。
    【解决方案2】:

    class_addMethod() 为类添加实例方法。您正在尝试添加一个类方法。因此,您需要将方法添加到元类 (classes are instances of their metaclasses),您可以通过以类为参数调用 object_getClass() 来获得:

    Class metaclass = object_getClass(NSClassFromString(@"NSColor"));
    
    BOOL success = class_addMethod(metaclass, @selector(colorWithWhite:alpha:), (IMP)fColorWithWhite, "@@:ff");
    

    【讨论】:

    • 没有成功。 class_addMethod 返回 false。
    • 嗯。它在这里工作。您正在测试什么 SDK?如果该方法已经存在(即在 10.9 上),它将失败。
    • 我正在针对 10.8 进行构建,以便我真正看到错误并且没有代码支持。目前我没有 10.9 之前的系统可以运行,所以这似乎是我在发布之前成功测试它的最佳选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-20
    • 1970-01-01
    • 1970-01-01
    • 2013-01-21
    • 2019-02-15
    相关资源
    最近更新 更多