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

Mar*_*ark 95 reflection objective-c

是否可以按名称创建类的实例?就像是:

NSString* className = @"Car";
id* p = [Magic createClassByName:className];
[p turnOnEngine];
Run Code Online (Sandbox Code Playgroud)

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

Chr*_*all 217

id object = [[NSClassFromString(@"NameofClass") alloc] init];
Run Code Online (Sandbox Code Playgroud)


Sim*_*ide 39

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

例如,在你的.h:

@property Class NameOfClass;
Run Code Online (Sandbox Code Playgroud)

然后在你的.m:

id object = [[NameOfClass alloc] init];
Run Code Online (Sandbox Code Playgroud)

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


Mar*_*ark 8

如果您正在使用Objective-C的工作没有NeXTstep(OS X,iOS,GNUstep等)的系统,或者你只是觉得这个方法更清洁,那么你可以利用Objective-C语言运行时库的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 ];
Run Code Online (Sandbox Code Playgroud)

在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 ];
Run Code Online (Sandbox Code Playgroud)

我没有测试过该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 + 1NeXTSTEPAPI.