Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does NSClassFromString affect performance?

I want to create a controller that depends on the class of a given instance of a model

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

I want to find a more flexible solution to this and thought of having a dictionary, which maps Model-Classes to Controller-Classes and then NSClassFromString could give me the right instance.

My question is this: Is NSClassFromString using much of my applications performance if i use it several times (say, 100 times at once)? Or would it be about as fast as the above approach?

like image 641
Tomen Avatar asked Sep 17 '26 01:09

Tomen


2 Answers

Generally, use of isMemberOfClass: in such a fashion indicates an architectural issue.

In this case, why can't the various Model classes simply implement a +controllerClass method?

I can understand Nikolai's desire to maintain the layering of Controller on top of Model without the Model having knowledge of the Controller. However, my experience is that any control layer that has such type specific knowledge of the Model quickly destroys that isolation anyway; the model layer quickly evolves behaviors that are controller specific.

Thus, the added complexity injected by attempting to maintain that separation just isn't worth it.

like image 50
bbum Avatar answered Sep 18 '26 19:09

bbum


A Class is an id, and as such can be added to an NSDictionary. You should try the following:

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

Then later:

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

If you make it a mutable dictionary, you can then have controllers register for the models they want instead of forcing the base class to be aware of all derived classes.

And a direct answer. At worst, NSClassFromString may need to iterate through all classes to find a match. It could also be a dictionary lookup, but the implementation is not documented and should not be relied on. While doing it a few hundred times probably isn't too bad, there are better ways.

like image 24
drawnonward Avatar answered Sep 18 '26 21:09

drawnonward



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!