NSClassFromString会影响性能吗?

时间:2010-05-26 17:13:45

标签: iphone objective-c

我想创建一个依赖于模型的给定实例的类的控制器

 -(BaseController *)getControllerForModel:(Model *)model
    {
     BaseController *controller = nil;
     Class controllerClass = [BaseController class]; //the default value

        //find the right controller
     if ([model isMemberOfClass:[ModelClass1 class]]) 
      controllerClass = [ConcreteController1 class];
     else if ([model isMemberOfClass:[ModelClass2 class]])
      controllerClass = [ConcreteController2 class];
     else if ([model isMemberOfClass:[ModelClass3 class]])
      controllerClass = [ConcreteController3 class];
...
     else if ([model isMemberOfClass:[ModelClassX class]])
      controllerClass = [ConcreteControllerX class];
     else
      Trace(TRACELEVEL_WARNING, @"Unrecognized model type: %@", NSStringFromClass([model class]));

     //Now instantiate it with the model
     controller = [[[controllerClass alloc] initWithModel:model] autorelease];
     return slotController;
    }

我想找到一个更灵活的解决方案,并想到有一个字典,它将Model-Classes映射到Controller-Classes,然后NSClassFromString可以给我正确的实例。

我的问题是:如果我多次使用它(例如,一次100次),NSClassFromString是否会使用我的应用程序的大部分性能?或者它会与上述方法一样快?

4 个答案:

答案 0 :(得分:5)

通常,以这种方式使用isMemberOfClass:表示存在架构问题。

在这种情况下,为什么各种Model类只能实现+controllerClass方法?

我可以理解Nikolai希望在没有模型知道控制器的情况下维持控制器在模型之上的分层。但是,我的经验是,任何具有模型特定类型知识的控制层都会迅速破坏隔离;模型层可以快速发展控制器特定的行为。

因此,试图维持这种分离所增加的复杂性并不值得。

答案 1 :(得分:3)

Class是一个id,因此可以添加到NSDictionary中。您应该尝试以下方法:

mModelToControllerMap = [[NSDictionary alloc] initWithObjectsAndKeys:
   [ConcreteController1 class] , [ModelClass1 class] ,
   [ConcreteController2 class] , [ModelClass2 class] ,
   ...
   nil];

然后:

controllerClass = [mModelToControllerMap objectForKey:[modelInstance class]];
if ( controllerClass ) ...
else ...

如果你把它变成一个可变字典,你就可以让控制器注册他们想要的模型,而不是强迫基类知道所有派生类。

直接回答。在最坏的情况下,NSClassFromString可能需要遍历所有类以查找匹配项。它也可以是字典查找,但实现没有记录,不应该依赖。虽然这样做几百次可能并不太糟糕,但有更好的方法。

答案 2 :(得分:2)

如果您真的关心性能,可以缓存NSClassFromString的结果并将它们放在字典中。

另一方面,这可能是NSClassFromString真正做的事情(地图查找)。所以我会说,100x if的速度要快得多。

但无论如何:只要试一试,就像所有性能问题一样。

答案 3 :(得分:2)

NSStringFromClass不应该贵得多。事实上,在您的情况下,您可以更有效地使用它。我不知道你确切的类命名约定,但使用像这样的方法可能会更小更快:

NSString * modelClassName = NSStringFromClass([model class]);

// get the suffix of class name
// for example, '3' in 'ModelClass3'
NSString * suffix = [modelClassName substringFromIndex:10];

// create the controller name
NSString * controllerName = [NSString stringWithFormat:@"ConcreteController%@", suffix];

/* do something if name is not valid */
controllerClass = NSClassFromString(controllerName);

正如bbum建议你也可以在模型类的公共父类上创建一个方法。