Можно ли создать экземпляр класса по имени? Что-то вроде:
NSString* className = @"Car";
id* p = [Magic createClassByName:className];
[p turnOnEngine];
Я не знаю, возможно ли это в objective-c, но похоже, что это будет,
Можно ли создать экземпляр класса по имени? Что-то вроде:
NSString* className = @"Car";
id* p = [Magic createClassByName:className];
[p turnOnEngine];
Я не знаю, возможно ли это в objective-c, но похоже, что это будет,
id object = [[NSClassFromString(@"NameofClass") alloc] init];
NSClassFromString()
запускает риск ошибочного использования имени класса или иным образом с использованием класса, который не существует. Если вы сделаете эту ошибку, вы не узнаете ее до выполнения. Вместо этого, если вы используете встроенный objective-c тип Class
для создания переменной, тогда компилятор проверяет, существует ли класс.
Например, в .h
:
@property Class NameOfClass;
а затем в .m
:
id object = [[NameOfClass alloc] init];
Если вы ошибочно указали имя класса или если оно не существует, во время компиляции вы получите сообщение об ошибке. Также я думаю, что это более чистый код.
Если вы работаете с 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 ];
В 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 )
для API 2.0 по сравнению с the sum of two pointers (isa, cstring)
, a size_t length (cstring_length)
и length of the string in bytes + 1
для NeXTstep
API.
@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];