2011-09-14 65 views
3

我用下面的代碼strugglig。我不會不喜歡它有什麼問題。 代碼被註釋相對於崩潰:問題與NSMutableDictionary setObject:forKey - 崩潰

- (IBAction) SavePreset: (id) sender 
{ 

NSString *presetName = [nameCombo stringValue]; // nameCombo is a NSComboBox* 
NSUserDefaults *vmDefaults = [NSUserDefaults standardUserDefaults]; 
NSMutableDictionary *projectionPresets = [vmDefaults objectForKey: kVmGeorefPresetKey]; 

BOOL doSave = YES; 

NSString *dictEntry = [projectionPresets objectForKey: presetName]; 
if (dictEntry) { 
    // this branch is not tested yet, plan to test when the rest is working. 
    int userChoice; 
    userChoice = NSRunAlertPanel(@"Save Preset", 
           @"This preset (%s) already exists, modify?", 
           @"OK", @"Cancel", nil, presetName); 
    doSave = (userChoice == NSAlertDefaultReturn); 
    if (doSave) { 
     [nameCombo addItemWithObjectValue: presetName]; 
    }   

} 

if (doSave) 
{ 
    // projParamText is of class NSTextField* 
    NSString *presetParam = [projParamText stringValue]; 

    // Up to this point, everything works as expected 
    // But, the following statement crashes silently. 
    [projectionPresets setObject: presetParam forKey: presetName]; 

    // and the subsequent code is never executed 
    [savePresetButton setEnabled: NO]; 
} 

} 

我不知道他的NSString *從返回[的NSControl stringValue的]返回一個指向內部字符串reperesentaion或一個新的NSString如果我編輯的文本不會改變之後的NSTextField。

+1

它默默崩潰?沒有任何例外或錯誤?你用斷點測試過嗎? – Joze

+0

您可以在調用stringValue之後檢查調試器的presetParam類型嗎?另外,請告訴我們任何崩潰日誌輸出 –

回答

0

嘗試[projectionPresets setValue: presetParam forKey: presetName];

另外的NSLog您presetName和presetParam並看看是否有這些都是零值。

5

發現罪魁禍首。下面statment是從文檔NSUserDefaults的:從返回的NSUserDefaults的

值是不可改變的,即使你設置了 可變對象的值。例如,如果將可變字符串 設置爲「MyStringDefault」的值,那麼稍後使用stringForKey檢索 的字符串將是不可變的。

解決方法是從舊的不可變的創建一個新的預設詞典,修改並將其存回用戶的默認值。

-1

要在一個NSMutableDictionary的setObject你必須首先做

NSMutableDictionary *projectionPresets = [[NSMutableDictionary alloc] init]; 

那麼只有你可以爲的setObject一個NSMutableDictionary。可變字典應該是絕對可變的。