16

我正在开发一个对象工厂来跟踪一小部分对象。对象可以是不同的类型,但它们都会响应createInstancereset。这些对象不能从公共基类派生,因为其中一些必须从内置的可可类派生,例如NSViewNSWindowController

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

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:

为了完整起见,这就是我要管理所有对象的原因。我希望能够通过调用[factory reset];.

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

5 回答 5

23

您可以使用以下函数将字符串转换为类:NSClassFromString

Class classFromString = NSClassFromString(@"MyClass");

不过,在您的情况下,您最好直接使用 Class 对象。

MyClass * variable = [factory makeObjectOfClass:[MyClass class]];

- (id)makeObjectOfClass:(Class)aClass
{
    assert([aClass instancesRespondToSelector:@selector(reset)]);
    id newInstance = [aClass createInstance];
    [managedObjects addObject:newInstance];
    return newInstance;
}
于 2008-11-24T21:58:45.040 回答
5

我有一个更好的教程,请查看 https://appengineer.in/2014/03/13/send-class-name-as-a-argument-in-ios/

于 2015-04-28T07:48:24.877 回答
3

动态指定一个类很容易,事实上你可以通过它的名字来引用它:

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

另一个提示,我会避免使用命名法“托管对象”,因为大多数其他 Cocoa 程序员会将其读作 NSManagedObject,来自 Core Data。您可能还会发现使用全局 NSNotification(所有可重置对象都订阅)而不是管理不同类型对象的集合更容易,但您比我更了解做出该决定。

于 2008-11-24T21:56:35.763 回答
3

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

于 2008-11-24T22:08:33.757 回答
2

听起来你想要这样的东西:

- (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]];
于 2008-11-24T21:55:14.063 回答