I am building a model for a MVC and I am experiencing an anomaly where contrary to the Apple Documentation "Values returned from NSUserDefaults are immutable, even if you set a mutable object as the value.", the [[NSUserDefaults standardUserDefaults] objectForKey:@"key"] is returning a mutable array.
I created an empty application for iOS in Xcode 4D199 to re-create the condition and confirm that it isn't accountable to other factors on my project.
I am setting the NSMutableArray as shown:
- (void)setupTest
{
NSMutableArray *mutableArray = [[NSMutableArray alloc] init];
[mutableArray addObject:@"one"];
[mutableArray addObject:@"two"];
[[NSUserDefaults standardUserDefaults] setObject:mutableArray forKey:@"mutableArray_01"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
and, I am getting the object as shown:
- (void)checkTest
{
NSMutableArray *mutableArrayInCheck = nil;
id whatIsThis = [[NSUserDefaults standardUserDefaults] objectForKey:@"mutableArray_01"];
if([whatIsThis isKindOfClass:[NSMutableArray class]])
{
NSLog(@"The array is mutable.");
mutableArrayInCheck = (NSMutableArray *)whatIsThis;
}
if([whatIsThis isKindOfClass:[NSArray class]])
{
NSLog(@"The array is immutable.");
}
if ([whatIsThis isMemberOfClass:[NSMutableArray class]])
{
NSLog(@"The array is a member of NSMutableArray class");
}
if (mutableArrayInCheck)
{
[mutableArrayInCheck addObject:@"three"];
NSLog([mutableArrayInCheck description]);
}
}
Now, according to the apple documentation, one would expect the console to only display the immutable line. But when I execute the code, the following lines are displayed in the console:
2012-01-05 18:47:33.328 Tester_01[78533:f803] The array is mutable.
2012-01-05 18:47:33.348 Tester_01[78533:f803] The array is immutable.
2012-01-05 18:47:33.349 Tester_01[78533:f803] (
one,
two,
three
)
So, I am wondering if there is something that I am missing here.
For additional information, the code that executes the tests is as shown:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
BOOL setupKey = NO;
if (setupKey)
{
[self setupTest];
}
BOOL checkKey = YES;
if (checkKey)
{
[self checkTest];
}
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
Initially, I ran the project with setupKey set to YES. After the first run, I changed the setupKey to NO. The console log is an outcome whilst the setupKey was set to NO. Let me know what you think.
NSMutableArrayto anNSArraypointer, because doing[NSArray arrayWithArray:mutableArray]would only be adding overhead, with very little benefit.