Agnar Renolen
Agnar Renolen

Reputation: 81

Problem with NSMutableDictionary setObject: forKey - crashes

I'm strugglig with the following code. I don't undesratnd what's wrong with it. Code is commented with respect to the crash:

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

}

I wonder whether he NSString* returned from [NSControl stringValue] returns a pointer to an internal string reperesentaion or a new NSString that will not change if I edit the text of the NSTextField later on.

Upvotes: 3

Views: 2105

Answers (3)

try catch finally
try catch finally

Reputation: 881

To setobject in an NSMutableDictionary you have to first do

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

Then only you can setobject for an NSMutableDictionary. The mutable dictionary should be an absolute mutable.

Upvotes: -1

Agnar Renolen
Agnar Renolen

Reputation: 81

Found the culprit. The following statment is from the NSUserDefaults documentation:

Values returned from NSUserDefaults are immutable, even if you set a mutable object as the value. For example, if you set a mutable string as the value for "MyStringDefault", the string you later retrieve using stringForKey: will be immutable.

The workaround is do create a new preset dictioary from the old immutable one, modify that and store it back with the user defaults.

Upvotes: 5

Eugene
Eugene

Reputation: 10045

try [projectionPresets setValue: presetParam forKey: presetName];

Also NSLog your presetName and presetParam and see if any of those are nil values.

Upvotes: 0

Related Questions