2012-03-29 89 views
2

我需要一個在運行時使用的字符串 - >字符串映射(想想NSDictionary),除非映射在構建時間後永遠不會改變。靜態字符串 - >字符串映射

天真的解決方案是隻使用NSDictionary,但必須有一個更優化的方式來做到這一點,不是嗎?

最佳的意義在於,如果映射在編譯時是已知的,並且從不改變,編譯器應該能夠在編譯時進行映射。 NSDictionary需要在運行時進行哈希查找。我知道這是不變的時間,但它只是對我來說有點「不潔」...

+1

「更優化」是什麼意思?你看到一些性能問題與NSDictionary,或者你只是假設必須有一個? – Caleb 2012-03-29 16:56:24

+0

更新我的問題以澄清我的意思是「最佳」。 – elsurudo 2012-03-30 15:58:09

+0

如果映射是「在運行時使用」,那麼編譯器如何根據第一句執行映射?你能解釋一下你想解決的問題嗎? – Caleb 2012-03-30 16:15:05

回答

1

靜態NSDictionary是正確的工具。您通常使用的方法+initialize初始化這些:

static NSDictionary *kDictionary; 

+ (void)initialize { 
    if (self == [MYClass class]) { 
    kDictionary = [[NSDictionary alloc] initWith...]; 
    } 
} 

initialize被稱爲每班一次,與線程安全,之前在第一個請求方法被調用這個類的(通常這第一種方法是+alloc)。 self測試是因爲子類將自動調用它們的[super initialize],並且在這種情況下您通常不希望多次運行這個測試。

+0

是否有任何理由不使用'dispatch_once()'警衛來進行初始化?這似乎更符合預期的限制,並且允許子類確保字典可用(如果其中一個在此類之前使用)。 – 2012-03-29 17:05:43

+0

你會把'dispatch_once()'放在哪裏?你可以把它放在'init'中,但是如果這個對象是用'initWithCoder:'創建的呢?如果有依賴於字典的類方法,可能會在第一個'init'之前調用呢? '+初始化'處理所有這些角落案例,並避免微妙和困難的錯誤。在實例方法中進行類初始化並不好。如果你在類方法中使用它,爲什麼不在正確的時間自動調用'+ initialize'? – 2012-03-29 17:49:40

+0

重新閱讀我的評論,現在對我來說似乎還不太清楚。對不起,我的意思是用'dispatch_once()'代替'if(self == [MYClass class])',在'+ initialize'內部,_not_在別處移動字典創建。然後,第一條消息繼承樹中的任何一個類都將創建該字典,並且不會有人重新創建它。是對的嗎? – 2012-03-29 18:04:13

3

如果這不是太麻煩(即它不是很大),你可以硬編碼你的NSDictionary,或者你可以創建一個plist並將其包含在您的應用程序包中。然後在應用程序啓動時,閱讀plist的字典(幾行代碼)。這些方法中的每一種都是大致相同的努力。使用plist的好處是,如果你必須改變它,你正在編輯plist,而不是代碼。

+0

這是我過去經常使用它的方式。但是,它仍然讓我覺得很骯髒,因爲你正在爲編譯時已知的某些東西進行運行時計算! – elsurudo 2012-03-30 16:00:57

+0

如果plist很大,運行時間可能會很大。但是有辦法將這個過程推到背景並減輕任何可感知的滯後。另一方面,你想維護什麼:代碼或plist?這裏的答案在一定程度上取決於數據的性質和大小。 – 2012-03-30 16:37:36

+1

好點,馬克。我同意維護一個PLIST是可取的,但這種情況下的數據量很小。但是,爲了簡單和可讀性,我可能會最終選擇PLISt路線。 – elsurudo 2012-03-30 16:57:16

相關問題