【发布时间】:2010-11-13 12:44:42
【问题描述】:
是否可以按名称创建类的实例?比如:
NSString* className = @"Car";
id* p = [Magic createClassByName:className];
[p turnOnEngine];
我不知道这在objective-c中是否可行,但似乎可以,
【问题讨论】:
是否可以按名称创建类的实例?比如:
NSString* className = @"Car";
id* p = [Magic createClassByName:className];
[p turnOnEngine];
我不知道这在objective-c中是否可行,但似乎可以,
【问题讨论】:
@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];
【讨论】:
NSClassFromString() 冒着错误输入类名或使用不存在的类的风险。如果你犯了那个错误,你直到运行时才会发现。相反,如果您使用 Class 的内置objective-c 类型来创建变量,那么编译器将验证该类是否存在。
例如,在您的.h:
@property Class NameOfClass;
然后在你的.m:
id object = [[NameOfClass alloc] init];
如果你输入了错误的类名或者它不存在,你会在编译时得到一个错误。我也认为这是更干净的代码。
【讨论】:
如果您在没有 NeXTstep(OS X、iOS、GNUstep 等)系统的情况下使用 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 用于NeXTSTEP API。
【讨论】:
id object = [[NSClassFromString(@"NameofClass") alloc] init];
【讨论】: