按名称创建objective-c类实例?

时间:2009-07-23 19:53:29

标签: objective-c reflection

是否可以按名称创建类的实例?类似的东西:

NSString* className = @"Car";
id* p = [Magic createClassByName:className];
[p turnOnEngine];

我不知道在Objective-c中这是否可能,但似乎是,

4 个答案:

答案 0 :(得分:217)

id object = [[NSClassFromString(@"NameofClass") alloc] init];

答案 1 :(得分:39)

NSClassFromString()冒着错误输入类名或使用不存在的类的风险。如果出现该错误,您将无法在运行时找到它。相反,如果使用内置的objective-c类型的Class来创建变量,那么编译器将验证该类是否存在。

例如,在.h

@property Class NameOfClass;

然后在.m

id object = [[NameOfClass alloc] init];

如果您错误输入了类名,或者它不存在,则在编译时会出错。另外我认为这是更清晰的代码。

答案 2 :(得分:8)

如果您在没有NeXTstepOS XiOSGNUstep等)系统的情况下使用Objective-C,或者您认为此方法更清晰,那么您可以利用Objective-C language runtime library's API。在Objective-C 2.0下:

#import <objc/runtime.h>
//Declaration in the above named file
id objc_getClass(const char* name);
//Usage
id c = objc_getClass("Object");
[ [ c alloc ] free ];

在Objective-C(1.0或未命名版本)下,您将使用以下内容:

#import <objc/objc-api.h>
//Declaration within the above named file
Class objc_get_class( const char* name);
//Usage
Class cls = objc_get_class( "Test" );
id obj = class_create_instance( cls );
[ obj free ];

我没有测试过1.0版本,但是我在现在正在生产的代码中使用了2.0函数。我个人认为,使用2.0函数比NS函数更干净,因为它占用的空间更少:the length of the name in bytes + 1 ( null terminator )用于2.0 API而不是the sum of two pointers (isa, cstring)size_t length (cstring_length),以及length of the string in bytes + 1 API的NeXTSTEP

答案 3 :(得分:2)

@interface Magic : NSObject
+ (id)createInstanceOfClass:(Class)classe;
@end

@implementation Magic

+ (id)createInstanceOfClass:(Class)classe
{
    return [[classe alloc] init];
}

@end

然后使用它:

Car *car = [Magic createInstanceOfClass:[Car class]];
[car engineTurnOn];