Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 如何将类名作为参数传递给cocoa中的对象工厂?_Objective C_Cocoa_Constructor_Factory - Fatal编程技术网

Objective c 如何将类名作为参数传递给cocoa中的对象工厂?

Objective c 如何将类名作为参数传递给cocoa中的对象工厂?,objective-c,cocoa,constructor,factory,Objective C,Cocoa,Constructor,Factory,我在一个对象工厂工作,以跟踪一小部分对象。对象可以是不同的类型,但它们都将响应createInstance和reset。无法从公共基类派生对象,因为其中一些对象必须从内置的cocoa类派生,如NSView和NSWindowController 我希望能够创建任何合适对象的实例,只需将所需的类名传递给我的工厂,如下所示: myClass * variable = [factory makeObjectOfClass:myClass]; makeObjectOfClass:方法如下所示: - (id

我在一个对象工厂工作,以跟踪一小部分对象。对象可以是不同的类型,但它们都将响应
createInstance
reset
。无法从公共基类派生对象,因为其中一些对象必须从内置的cocoa类派生,如
NSView
NSWindowController

我希望能够创建任何合适对象的实例,只需将所需的类名传递给我的工厂,如下所示:

myClass * variable = [factory makeObjectOfClass:myClass];
makeObjectOfClass:
方法如下所示:

- (id)makeObjectOfClass:(CLASSNAME)className
{
    assert([className instancesRespondToSelector:@selector(reset)]);
    id newInstance = [className createInstance];
    [managedObjects addObject:newInstance];
    return newInstance;
}
是否有一种方法可以将类名传递给方法,就像我在上面使用
makeObjectOfClass:
(CLASSNAME)CLASSNAME
参数所做的那样

为了完整性,下面是我想要管理所有对象的原因。我希望能够通过调用
[factory reset],一次性重置整套对象

- (void)reset
{
    [managedObjects makeObjectsPerformSelector:@selector(reset)];
}

听起来你想要的是:

- (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]];

动态指定一个类非常容易,事实上,您可以通过它的名称引用它:

id string = [[NSClassFromString(@"NSString") alloc] initWithString:@"Hello!"];
NSLog( @"%@", string );

另一个技巧是,我会避免使用术语“托管对象”,因为大多数其他Cocoa程序员会从核心数据中将其理解为NSManagedObject。您可能还发现使用全局NSNotification(所有可重置对象都订阅)而不是管理不同类型对象的集合更容易,但您比我更容易做出决定。

您可以使用函数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;
}

其他答案中缺少的一点答案是,您可以定义一个包含
+createInstance
+reset
方法的
@protocol

我有一个更好的教程,请查看

谢谢你的提示!我正计划使用一个协议,但我觉得没有必要在问题中提及它。我在迈克尔·蔡(Michael Tsai)和马特·加拉赫(Matt Gallagher)的答案之间左右为难。我对两者都投了更高的票,因为两者都提到了“Class”的用法,这正是我想要的。最后,我选择了Matt的答案,因为它强调“Class”而不是“ClassFromString”,而且在编辑之前,它是第一个提到“Class”的用法的。@Ned Batchelder:谢谢你更改标记。出于某种原因,“objective-c”在我向问题添加标记时出现的标记下拉列表中显示的项目比“objective-c”多得多(大约200个),但我现在看到“objective-c”已重定向到“objective-c”@eJames:您的问题显示-reset被发送到实例,而不是类对象,因此我认为[aClass respondsToSelector:@selector(重置)]在Matt Gallagher中,他的回答是错误的。@Michael Tsai:很好的回答!我不会注意到。Matt一定复制了我的示例,其中的方法调用也不正确。谢谢提醒。我已将问题中的代码改为使用InstanceRespondtoSelector。“类”类型和[MyClass类]这正是我想要的。谢谢!Michael Tsai指出[aClass respondsToSelector:@selector(reset)]行应该改为[aClass InstanceRespondsToSelector:@selector(reset)]。我正在修改我的问题,您可能希望在回答中也这样做。谢谢您的回答。我将使用[MyClass类]您在编辑中提到的方法。除非您是为Objective-C++编译,否则您可以将变量命名为“class”。关于NSManagedObject的观点很好。我将更改我的问题以避免可能的混淆。