是否可以按名称创建类的实例?类似的东西:
NSString* className = @"Car";
id* p = [Magic createClassByName:className];
[p turnOnEngine];
我不知道在Objective-c中这是否可能,但似乎是,
答案 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)
如果您在没有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
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];