NSUserDefaults returns a mutable array

I am creating a model for MVC and I have an anomaly where, contrary to the Apple Documentation, "The values โ€‹โ€‹returned from NSUserDefaults are immutable, even if you set the mutable object to value. , The [[NSUserDefaults standardUserDefaults] objectForKey: @" key "] returns an array mutable .

I created an empty iOS app in Xcode 4D199 to recreate the condition and confirm that it does not respond to other factors in my project.

I install 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 get an 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 documentation for the apple, one would expect the console to display only an immutable line . But when I run 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 more information, the code that runs the tests is 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; } 

I initially ran the project with setupKey set to YES . After the first run, I changed setupKey to NO . The console log is the result, while setupKey is set to NO . Let me know what you think.

+6
source share
2 answers

Strictly speaking, you are right. The statement "Return Values โ€‹โ€‹are Unchanged" is confusing because it makes it look like getting a mutable object should be impossible. However, the statement should be read as "Returned values โ€‹โ€‹cannot be guaranteed by variability." This way, even if you store the modified array when you read the value back, you will get an NSArray object (which may be an object of a variable class of NSMutableArray descendants, but this cannot be guaranteed and may vary depending on the run or depends on the contents of the array).

+2
source

the isKindOfClass method is not suitable for a cluster of classes

the following paragraph is in the documentation

Use caution when using this method for objects represented by a cluster of classes. Due to the nature of class clusters, the returned object may not always be the type you expected. If you call a method that returns a cluster of classes, the exact type returned by the method is the best indicator of what you can do with this object. For example, if a method returns a pointer to an NSArray object, you should not use this method to check if the array is volatile, as shown in the following code:

  // DO NOT DO THIS! //if ([myArray isKindOfClass:[NSMutableArray class]]) //{ // Modify the object //} 
+1
source

Source: https://habr.com/ru/post/905276/


All Articles