向Objective-C中的对象动态添加方法?

向Objective-C中的对象动态添加方法?,objective-c,dynamic,reflection,Objective C,Dynamic,Reflection,我想在Objective-C中使用JavaScript: var obj = {}; obj.myFunc = function() { ... }; 这可能吗?或者方法只能添加到Objective-C中的类中,而不能添加到对象中?也就是说,我找到了class\u addMethod,但我想找到一种方法,在同一类的不同实例上实现同一选择器 这是可能的还是我解决了?在Objective-C中,方法(甚至实例方法)只在类上定义,而不是在单个对象上定义 您可以在运行时使用objc\u allocat

我想在Objective-C中使用JavaScript:

var obj = {};
obj.myFunc = function() { ... };
这可能吗?或者方法只能添加到Objective-C中的类中,而不能添加到对象中?也就是说,我找到了
class\u addMethod
,但我想找到一种方法,在同一类的不同实例上实现同一选择器

这是可能的还是我解决了?

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

您可以在运行时使用
objc\u allocateClassPair
创建一个新类,并向该类添加方法。您可以在运行时使用
object\u 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
在Objective-C中,方法(甚至实例方法)仅在类上定义,而不是在单个对象上定义

您可以在运行时使用
objc\u allocateClassPair
创建一个新类,并向该类添加方法。您可以在运行时使用
object\u 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);
}

不可能。在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);
}

谢谢,这绝对有帮助。我现在的想法是动态创建单个类,在该类上设置选择器的实现,然后在泛型实例上转发调用(为处理该类而编写的类)但我关心的是,一旦创建并注册了一个类,似乎没有任何方法可以动态地销毁或解除锁定它。你是对的。创建类后,不能将其删除。实例不保留其类,因此运行时无法确保删除类是安全的。谢谢,这确实有帮助。我现在的想法是动态创建单个类,在该类上设置选择器的实现,然后在泛型实例上转发调用(为处理该类而编写的类)但我关心的是,一旦创建并注册了一个类,似乎没有任何方法可以动态地销毁或解除锁定它。你是对的。创建类后,不能将其删除。实例不保留其类,因此运行时无法确保删除类是安全的。