2009-07-23 120 views
90

是否可以按名称创建类的实例?喜欢的东西:按名称创建objective-c类实例?

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

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

回答

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

这不会引起任何泄漏? – AntiMoron 2016-11-30 07:48:22

38

NSClassFromString()运行错误输入的类名或以其它方式使用的风险不存在的类。如果你犯了这个错误,你将不会在运行时才发现。相反,如果您使用内置的objective-c类型Class来创建变量,那么编译器将验证该类是否存在。

例如,在你的.h

@property Class NameOfClass; 

,然后在.m

id object = [[NameOfClass alloc] init]; 

如果你输入了错误的类名,或者如果它不存在,你会得到一个编译时错误。另外我认为这是更简洁的代码。

+1

克里斯你可以投票吗? – 2011-05-16 00:53:12

8

如果您正在使用Objective-C的工作没有NeXTstepOS XiOSGNUstep等)的系统,或者你只是觉得这个方法更清洁,那么你可以利用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功能更清洁,因为它消耗的空间更少:2.0 API的the length of the name in bytes + 1 (null terminator)the sum of two pointers (isa, cstring)size_t length (cstring_length)length of the string in bytes + 1NeXTSTEP API。

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];