Veeru
Veeru

Reputation: 4936

iphone xcode; mutableCopy still immutable?

i have looked all over the place regarding this problem. All i am trying to do is, create a nsuser defaults object, then add a mutable array to it and try to modify the nsuserdefaults object.

//Created a sample array
NSMutableArray *xml=[[NSMutableArray alloc] init];
[xml addObject:@"x"];
[xml addObject:@"x"];
[xml addObject:@"x"];
[xml addObject:@"x"];
[xml addObject:@"x"];
//assigned to defaults object which is created previously with a mutableCopy
[defaults  setObject:[xml mutableCopy] forKey:@"userLocationsDetailedXML"]; 
//Tried to modify the defaults object - which at this point should be mutable
[[defaults objectForKey:@"userLocationsDetailedXML" ] replaceObjectAtIndex:1 withObject:@"y"] ;

Adding [defaults synchronize] does'nt help either.

But surprisingly the defaults object is still immutable. It is __NSCFArray, not __NSCFArrayM as expected Any suggestions?

edit: console output Class : __NSCFArray => SHould'nt it be _NSCFArrayM since i created a mutable copy? [_NSCFArray replaceObjectAtIndex:withObject:]: mutating method sent to immutable object'

Upvotes: 0

Views: 1290

Answers (2)

Sam Ritchie
Sam Ritchie

Reputation: 11038

Try casting the array as NSMutableArray, using

[(NSMutableArray *)[defaults objectForKey:@"userLocationsDetailedXML"] replaceObjectAtIndex:1 withObject:@"y"] ;

that should take care of it.

EDIT:

Given that you can't actually store NSMutableArrays in NSUserDefaults, I recommend that you just go ahead and reassign the entire thing, like so:

NSMutableArray *xml = [[NSMutableArray alloc] init];
    [xml addObject:@"x"];
    [xml addObject:@"x"];
    [xml addObject:@"x"];
    [xml addObject:@"x"];
    [xml addObject:@"x"];

[defaults  setObject:xml forKey:@"userLocationsDetailedXML"]; 
[xml release];

Then, for changing the values,

NSMutableArray *userLoc = [[defaults objectForKey:@"userLocationsDetailedXML"] mutableCopy];
[userLoc replaceObjectAtIndex:1 withObject:@"y"];
[defaults  setObject:userLoc forKey:@"userLocationsDetailedXML"]; 
[userLoc release]; //thanks, dreamlax!

Upvotes: 1

dreamlax
dreamlax

Reputation: 95325

From the 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.

Also, you have a rather ugly leak; you are the owner of the object returned by mutableCopy but you have no way to relinquish ownership because you have lost the only reference to that object (the xml array is mutable anyway).

Upvotes: 5

Related Questions