During the project, I encountered the use of object arrays: Contact Interface, which requires partition display. If I store an array and then rearrange it every time I display, I find that there will be a computing delay. All of my partitions are first placed in a dictionary in a singleton class. When I needed to use the contact's interface to define an additional NSDictionary assignment to it, trying to modify NSDictionary, I found that the array objects stored in the singleton class had also been modified. I feel very speechless. At that time, my nesting was like this.
NSDictionary@{key1:NSMutableArray @ [Object 1, Object 2],key2:NSMutableArray @ [Object 3, Object 4],...}
It is in a single case class that the attribute of an immutable dictionary NSDictionary is defined and n variable arrays NSMutableArray are stored, which can dynamically increase or delete the objects stored in the array.
On the Internet, I saw deep copies of many objects and shallow copies of copy/mutableCopy. And I have implemented the NSCoding protocol. But all of them were found to be ineffective. So I wrote a Test project and found a problem.
NSArray *array1 = [NSArray arrayWithObjects:@"a", nil];
NSMutableArray *arry2 = [array1 mutableCopy];
[arry2 replaceObjectAtIndex:0 withObject:@"b"];
NSLog(@"%@",array1);
So the output is still @[a]
But when I define two Person objects that implement the NSCoding protocol and have a name attribute and put them in an array
Person *person1 = [[Person alloc] init];
person1.name = @"a";
NSArray *array1 = [NSArray arrayWithObjects:person1, nil];
NSArray *arry2 = [NSArray arrayWithArray:array1];
[arry2 enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
Person *person = obj;
person.name = @"c";
}];
NSLog(@"%@",array1);
The output Person's name is c
Some people say that if you want to copy objects in an array in depth, you have to rebuild an array and then give a new array in a loop, that is:
Person *person1 = [[Person alloc] init];
person1.name = @"a";
NSArray *array1 = [NSArray arrayWithObjects:person1, nil];
NSMutableArray *arrayM = [NSMutableArray arrayWithCapacity:0];
[array1 enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
Person *person = [obj copy];
person.name = @"c";
[arrayM addObject:person];
}];
NSLog(@"%@",array1);
And the object must copy when traversing, otherwise it is difficult to achieve deep copy.
Later, another method was found by [NSKeyed Unarchiver unarchiveObjectWithData:[NSKeyed Archiver Archived Data WithRootObject:];
Person *person1 = [[Person alloc] init];
person1.name = @"a";
Person *person2 = [[Person alloc] init];
person2.name = @"b";
NSArray *array1 = [NSArray arrayWithObjects:person1, nil];
NSArray *array2 = [NSArray arrayWithObjects:person2, nil];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:array1,@"a",array2,@"b", nil];
[Object shareObject].dict = dict;
NSLog(@"1:%@",[Object shareObject].dict);
NSDictionary *temDict = [[Object shareObject].dict mutableCopy];
NSMutableArray *arrayM = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:[temDict objectForKey:@"a"]]];
[arrayM enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
Person *person = obj;
person.name = @"c";
}];
NSLog(@"2:%@",[Object shareObject].dict);
And no matter how many layers you nest, as long as each layer implements the NSCoding protocol, deep copy can also be achieved. Later, I abandoned putting contacts in singleton classes and placed them directly in local files.