0

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

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

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

这是可能的还是我是 SOL?

4

2 回答 2

5

在 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
于 2013-04-19T21:23:22.057 回答
1

不是直接可以的。在 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);
}
于 2013-04-19T21:27:21.720 回答