Как передать имя класса в качестве аргумента для объекта factory в cocoa?
Я работаю над объектом factory, чтобы отслеживать небольшую коллекцию объектов. Объекты могут быть разных типов, но все они будут реагировать на createInstance
и reset
. Объекты не могут быть получены из общего базового класса, потому что некоторые из них должны будут выводиться из встроенных классов cocoa, таких как NSView
и NSWindowController
.
Я хотел бы иметь возможность создавать экземпляры любого подходящего объекта, просто передав нужное имя класса моему factory следующим образом:
myClass * variable = [factory makeObjectOfClass:myClass];
Метод makeObjectOfClass:
будет выглядеть примерно так:
- (id)makeObjectOfClass:(CLASSNAME)className
{
assert([className instancesRespondToSelector:@selector(reset)]);
id newInstance = [className createInstance];
[managedObjects addObject:newInstance];
return newInstance;
}
Есть ли способ передать имя класса методу, как это было сделано с аргументом (CLASSNAME)className
в makeObjectOfClass:
выше?
Для полноты, вот почему я хочу управлять всеми объектами. Я хочу, чтобы reset полный набор объектов в один кадр, вызывая [factory reset];
.
- (void)reset
{
[managedObjects makeObjectsPerformSelector:@selector(reset)];
}
Ответы
Ответ 1
Вы можете преобразовать строку в класс с помощью функции: NSClassFromString
Class classFromString = NSClassFromString(@"MyClass");
В вашем случае, однако, вам лучше использовать объекты класса напрямую.
MyClass * variable = [factory makeObjectOfClass:[MyClass class]];
- (id)makeObjectOfClass:(Class)aClass
{
assert([aClass instancesRespondToSelector:@selector(reset)]);
id newInstance = [aClass createInstance];
[managedObjects addObject:newInstance];
return newInstance;
}
Ответ 2
У меня есть правильный учебник по этому вопросу, пожалуйста, проверьте
https://appengineer.in/2014/03/13/send-class-name-as-a-argument-in-ios/
Ответ 3
Довольно легко динамически указать класс, на самом деле вы можете просто ссылаться на него по имени:
id string = [[NSClassFromString(@"NSString") alloc] initWithString:@"Hello!"];
NSLog( @"%@", string );
Еще один совет, я бы не использовал номенклатурный "управляемый объект", так как большинство других программистов Cocoa будут читать это как NSManagedObject, из Core Data. Вам также может быть проще использовать глобальную NSNotification (чтобы все ваши reset -able объекты подписывались) вместо управления коллекцией различных типов объектов, но вы более информированы о принятии этого решения, чем я.
Ответ 4
Бит ответа, отсутствующий в других ответах, заключается в том, что вы можете определить @protocol
, содержащий ваши методы +createInstance
и +reset
.
Ответ 5
Похоже, вы хотите что-то вроде:
- (id)makeObjectOfClassNamed:(NSString *)className
{
Class klass = NSClassFromString(className);
assert([klass instancesRespondToSelector:@selector(reset)]);
id newInstance = [klass createInstance];
[managedObjects addObject:newInstance];
return newInstance;
}
Это предполагает метод класса с именем +createInstance
. Или вы можете просто использовать [[klass alloc] init]
.
Чтобы вызвать его:
MyClass *variable = [factory makeObjectOfClassNamed:@"MyClass"];
В зависимости от того, что вы пытаетесь сделать, может быть лучше передать объекты класса, чем строки, например:
MyClass *variable = [factory makeObjectOfClass:[MyClass class]];