Depth copy

Deep copy: create a new space, then return its address, modify the original object, the new object is not affected. Shallow copy: Returns the address of the original object.Copy the code

NSString& mutableString

   NSMutableString* mutabelstring = [NSMutableString stringWithString:@"abc"];
    self.pname = mutabelstring;
    [mutabelstring appendString:@"wwwwwwwwww]"];
    NSLog(@"mutableString:%@,self.pname:%@",mutabelstring,self.pname);
Copy the code

Print the result when @property (nonatomic, strong) NSMutableString *pname

Print the result when @property (nonatomic, copy) NSMutableString *pname

NSMutableArray

NSMutableArray* stringArray1 = [NSMutableArray arrayWithArray:@[@"a",@"b",@"c",@"d"]];
NSLog(@"%p-%p-%p",stringArray1,[stringArray1 copy],[stringArray1 mutableCopy]);
NSLog(@"%@-%@-%@",stringArray1.class,[[stringArray1 copy] class],[[stringArray1 mutableCopy] class]);
Copy the code

The first line prints the address of the array and the second line prints the type of the array.

   0x2831335a0 - 0x2831334e0 -  0x283133720
  __NSArrayM-  __NSFrozenArrayM-  __NSArrayM
Copy the code

For mutable arrays, both copy and mutablecopy create a new address to store the original value, so both are deep copies. Of course, copy will be an immutable array, and mutablecopy will be a mutable array. So this is definitely going to be a problem in the code.

@property (nonatomic, copy) NSMutableArray *array;

NSArray

NSArray* stringArray1 = @[@"a",@"b",@"c",@"d"];
NSLog(@"%p-%p-%p",stringArray1,[stringArray1 copy],[stringArray1 mutableCopy]);
NSLog(@"%@-%@-%@",stringArray1.class,[[stringArray1 copy] class],[[stringArray1 mutableCopy] class]);
Copy the code

Take a look at the print result:

   0x282874990- 0x282874990- 0x282874a50
   __NSArrayI- __NSArrayI- __NSArrayM
Copy the code

For an immutable array, copy is a shallow copy of the same address, the new array is an immutable array, mutablecopy is a deep copy, the address has changed, the new array is a mutable array.

Multilayer deep copy

Sometimes we have a need like this:

NSMutableString* string = [NSMutableString stringWithString:@”a”];

NSArray* array = @[string,@"b",@"c",@"d"];


[string appendString:@"dddd"];
NSLog(@"%@",[array mutableCopy]);
Copy the code

The first element of the array changes. Print the result (adddd, b, c, d). This is because what we call a deep copy is just a single layer copy. It just regenerates an array, and the array still holds the pointer value of the original object. NSMutableArray * stringArray1 = [[NSMutableArray alloc]initWithArray:array copyItems:YES]; A, B, C, D But this function can only be copied one layer deep, if so: NSMutableString* string = [NSMutableString stringWithString:@”a”];

 NSArray* array = @[@[string,@"b",@"c",@"d"],@"bb",@"cd",@"dd"];

NSMutableArray * stringArray1 = [[NSMutableArray alloc]initWithArray:array copyItems:YES];

[string appendString:@"dddd"];
NSLog(@"%@-%@",stringArray1,[array mutableCopy]);
Copy the code

Print the results as follows ((adddd, b, c, d), bb, CD, dd) – ((adddd, b, c, d), bb, CD, dd)

NSMutableString* String = [NSMutableString stringWithString:@” A “]; NSArray* array = @[@[string,@”b”,@”c”,@”d”],@”bb”,@”cd”,@”dd”];

 NSMutableArray * stringArray1  = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:array]];

[string appendString:@"dddd"];
NSLog(@"%@-%@",stringArray1,[array mutableCopy]);
Copy the code

Print the following: ((a, b, c, d), bb, CD, dd)-((adddd, b, c, d), bb, CD, dd)

Conclusion:

When modifying properties of mutable types, such as NSMutableArray, NSMutableDictionary, and NSMutableString, use strong.

When modifying properties of immutable types, such as NSArray, NSDictionary, and NSString, use copy.

For immutable groups, copy is a shallow copy and mutablecopy is a deep copy. For mutable arrays, both copy and mutablecopy are deep copies. What we call a deep copy is actually only one layer, and if the array contains subarrays, it does not work. In this case, to ensure full copy, archive should be used.