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