Objective-C - 对象是否有一种方法可以直接执行IMP方法,就像它自己一样?

时间:2014-04-12 10:41:50

标签: objective-c objective-c-blocks objective-c-runtime

假设我有一个Object,一个MyClass的实例。在Objective-C中,可以通过发送消息或使用NSObject的“perform”来要求Object“执行”选择器。

此选择器必须在编译时定义为类定义的一部分,更准确地说,作为该类的实例方法或在Obj-C运行时的帮助下,将方法添加到(整个)MyClass中运行时使用class_addMethod。

我的问题如下:

是否可以向IMP发送一个对象,并要求它自己执行它?基本上我想要对象,MyClass的不同实例自己执行事情,而整个MyClass都不知道它。本质上我会称这些为“每个对象方法”,一个Object1将自己的IMP执行,然后另一个Object2获得不同的IMP,依此类推。这些IMP存储在其他地方,它就是知道并决定发送内容的对象。

2 个答案:

答案 0 :(得分:0)

是的,有效吗

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

@interface DonorTemplateClass : NSObject
- (void)testMethod:(NSString*)aStringAsParameter;
@end
@implementation DonorTemplateClass
- (void) testMethod:(NSString*)aStringAsParameter {
    NSLog(@"%@ :: %@", self.class, aStringAsParameter);
}
@end

@interface AClass : NSObject
@end
@implementation AClass
@end

@interface AnotherClass : NSObject
@end
@implementation AnotherClass
@end

int main(int argc, char *argv[]) {
    @autoreleasepool {
        SEL justTheMethodSelector = @selector(testMethod:);
        IMP justTheMethodImplementation = class_getMethodImplementation([DonorTemplateClass class], justTheMethodSelector);

        AClass *anAClassInstance = [[AClass alloc] init];
        AnotherClass *anotherClassInstance = [[AnotherClass alloc] init];

        NSString *aString = @"Test1";

        typedef void (*MyTypeName)(id,SEL, NSString*); // more info about the block syntax on http://goshdarnblocksyntax.com scroll down to "typedef"
        MyTypeName blockName = (MyTypeName)justTheMethodImplementation;

        blockName(anAClassInstance, justTheMethodSelector, aString);
        blockName(anotherClassInstance, justTheMethodSelector, aString);
    }
}

请注意我将IMP转换为typedef指针类型。当我打电话给我时它编译得很好但是objc_retain然后崩溃了...所以我说你需要输入typedef在使用它们之前你的IMP,但是你可以在任何合适的类的上下文中执行它们

答案 1 :(得分:0)

IMP只是常规C函数指针的typedef。它的意思是指向方法实现,它是C函数,第一个参数是对象,第二个参数是选择器。并且&#34;执行IMP&#34;的对象只是意味着调用C函数,将对象作为第一个参数传递,将选择器作为第二个传递。

你说你希望能够向IMP发送一个对象并要求它自己执行它&#34; (即调用IMP传递对象和选择器),但你不希望&#34;整个MyClass知道它&#34; (我认为这意味着你不希望它作为一种方法)。

所以基本上,听起来你只需要一堆独立的C函数,而不是你可以调用的方法,根据需要传递各种对象。您可以根据需要存储这些C函数指针。是吗?