2010-05-26 145 views
2

我想創建一個控制器,它依賴於類的模型NSClassFromString會影響性能嗎?

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

我想找到一個更靈活的解決方案,這一點,並認爲擁有一本字典,其模型的類映射到的給定實例控制器類,然後NSClassFromString可以給我正確的例子。

我的問題是:NSClassFromString如果我多次使用它(例如,一次100次),那麼我的應用程序的性能會如何?或者它會像上述方法一樣快?

回答

3

一個類是一個ID,因此可以添加到一個NSDictionary。你應該嘗試以下操作:

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

再後來:

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

如果你讓一個可變的字典,您就可以擁有控制器的型號註冊,他們希望,而不是強迫的基類是意識到所有派生類。

並直接回答。在最壞的情況下,NSClassFromString可能需要遍歷所有類以找到匹配項。它也可以是字典查找,但實現沒有記錄,不應該依賴。雖然這樣做幾百次可能不算太壞,但有更好的辦法。

+0

我知道這個答案已被接受很長一段時間,但不幸的是,我認爲它有根本的缺陷。 'NSDictionary'鍵不應該只是'id's,它們應該是實現'NSCopying'協議的'id's。 'Class'不這樣做,因此實例不能安全地用作鍵。令人遺憾的是,您留下了存儲類名稱並再次調用「NSClassFromString」。 – camdez 2014-01-21 22:20:56

5

通常,以這種方式使用isMemberOfClass:表示一個架構問題。

在這種情況下,爲什麼各種Model類不能簡單地實現+controllerClass方法?

我可以理解尼古拉希望保持控制器在模型之上的分層而不需要模型掌握控制器的知識。然而,我的經驗是,任何具有該模型類型特定知識的控制層都會很快破壞隔離;模型層快速發展控制器特定的行爲。

因此,試圖維持這種分離所增加的複雜性是不值得的。

+0

保持控制器層不在模型中對我來說似乎是正確的。 – 2010-05-26 17:23:45

+2

跳過籃圈真的不能保持隔離並造成不必要的複雜性。同樣,這樣的設計實際上並不是孤立的控制器形式模型,因爲控制器與模型緊密交織在一起。 – bbum 2010-05-26 18:10:51

+0

但是它將模型與控制器層隔離,這通常是件好事。特別是當模型層被設計爲重用時。 – 2010-05-26 19:26:22

2

如果您真的關心性能,可以緩存NSClassFromString的結果並將它們放入字典中。

另一方面,這可能幾乎是NSClassFromString真正做的(地圖查找)。所以我會說100倍速的方法要快得多。

但無論如何:只要嘗試一下,就像所有性能問題一樣。

+0

我認爲NSClassFromString也會獲得運行時鎖定,從而減慢其他線程/旋轉。 – 2010-05-27 03:30:09

2

NSStringFromClass不應該昂貴得多。事實上,在你的情況下,你可以更有效地使用它。我不知道你的確切類命名慣例,但使用這樣的methof可能是更小,更快:

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建議你也能做出這樣的模型類的公共父的方法。