在Objective-C中动态地向对象添加方法



我想在Objective-C中做这个JavaScript:

var obj = {};
obj.myFunc = function() { ... };

这可能吗?或者方法只能添加到Objective-C中的中,而不能添加到对象中?即,我发现class_addMethod,但我想要一种方法,有不同的实现相同的选择器在同一类的不同实例。

这是可能的还是我是SOL?

在Objective-C中,方法(甚至是实例方法)只能在类上定义,而不能在单个对象上定义。

您可以在运行时使用objc_allocateClassPair创建一个新类,并向该类添加方法。您可以在运行时使用object_setClass更改对象的类。如果你决定研究这个,你需要做一些关于"isa-swizzling"的研究。如果你想在对象上使用它,你也将与KVO一起使用,这是特别有问题的。

如果你可以简单地改变你的API来使用块,那将会简单得多。例子:

@interface MyObject : NSObject
- (void)myMethodWithString:(NSString *)string;
typedef void (^MyMethodBlock)(NSString *string);
@property (nonatomic, copy) MyMethodBlock myMethodBlock;
@end
@implementation MyObject
@synthesize myMethodBlock = _myMethodBlock;
- (void)myMethodWithString:(NSString *)string {
    MyMethodBlock block = self.myMethodBlock;
    if (block) {
        block(string);
    }
}
@end

不可能。在JavaScript中,对象从其他对象继承,而在Objective-C中,继承是通过类实现的。

我不明白你为什么需要这个,可能你有一个设计问题,你向我们展示了一个XY问题。然而,这里有一个我能想到的非常丑陋的解决方案,只是为了教育目的。

id dispatch_helper(id obj, SEL sel, id arg)
{
    id (^blk)(id, SEL, id) = objc_getAssociatedObject(obj, sel);
    return blk(obj, sel, arg);
}
void object_addMethod(id obj, SEL sel, IMP imp)
{
    class_addMethod(object_getClass(obj), sel, dispatch_helper, "@@:@");
    objc_setAssociatedObject(obj, sel, ^(id o, SEL s, id a) {
        return IMP(o, s, a);
    }, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

相关内容

  • 没有找到相关文章