This article has been synchronized to brief book :iOS – Deep copy, shallow copy exploration verification

1. The concept

Shallow copy: The copied object points to the same address as the original object

Deep copy: The copied object points to a new address

2. Non-collection objects

  1. #### Non-collection class immutable objects
    NSString *str1 = @"hello world";
    NSString *str2 = [str1 copy];
    NSString *str3 = [str1 mutableCopy];
    
    NSLog(@"\n str1 = %p class = %@", str1, str1.class);
    NSLog(@"\n str2 = %p class = %@", str2, str2.class);
    NSLog(@"\n str3 = %p class = %@", str3, str3.class);
Copy the code

The output

2021-05-08 17:09:47.697211+0800 AlgorithmDemo[33483:14523594] 
 str1 = 0x100008220 class = __NSCFConstantString
 str2 = 0x100008220 class = __NSCFConstantString
 str3 = 0x10044f8d0 class = __NSCFString
Copy the code

From printing:

  • For immutable objects of non-collection classes, copy is a shallow copy and mutableCopy is a deep copy
  • The shallow-copy returns the same address as the original object, and returns an immutable object.
  • The deep copy returns a new memory address and returns a mutable object

####2. Non-collection class mutable objects

    NSString *str1 = [NSMutableString stringWithString:@"hello world"];
    NSMutableString *str2 = [str1 copy];
    NSMutableString *str3 = [str1 mutableCopy];
    
    NSLog(@"\n str1 = %p class = %@", str1, str1.class);
    NSLog(@"\n str2 = %p class = %@", str2, str2.class);
    NSLog(@"\n str3 = %p class = %@", str3, str3.class);
Copy the code

The output

2021-05-08 17:10:45.047818+ AlgorithmDemo[33588:14525427] str1 = 0x1029045f0 class = __NSCFString str2 = 0x102904640  class = __NSCFString str3 = 0x102904760 class = __NSCFStringCopy the code

Available by printing

  • Non-collection class mutable object copy is a deep copy
  • Non-collection class mutable object mutable object is a deep copy
  • Both copy and mutableCopy return mutable objects

3. Collection objects

Collection class immutable objects

NSString *str1 = @"hello world"; NSMutableString *str2 = [NSMutableString stringWithString:@"hello world"]; NSArray *array1 = [NSArray arrayWithObjects: str1, str2, nil]; NSArray *array2 = [array1 copy]; NSArray *array3 = [array1 mutableCopy]; NSLog(@"\n array1 = %p class = %@ \n", array1, [array1 class]); NSLog(@"\n array2 = %p class = %@ \n", array2, [array2 class]); NSLog(@"\n array3 = %p class = %@ \n", array3, [array3 class]); NSLog(@"\n\n======== element is String ======== "); NSLog(@"\n obj0 = %p class = %@ \n", array1[0], [array1[0] class]); NSLog(@"\n obj0 = %p class = %@ \n", array2[0], [array2[0] class]); NSLog(@"\n obj0 = %p class = %@ \n", array3[0], [array3[0] class]); NSLog (@ "\ n \ n = = = = = = = = element is mutableString = = = = = = = ="); NSLog(@"\n obj1 = %p class = %@ \n", array1[1], [array1[1] class]); NSLog(@"\n obj1 = %p class = %@ \n", array2[1], [array2[1] class]); NSLog(@"\n obj1 = %p class = %@ \n", array3[1], [array3[1] class]);Copy the code

The output

2021-05-08 17:34:32.740896+0800 AlgorithmDemo[39309:14557776] array1 = 0x102904180 class = __NSArrayI array2 = 0x102904180 class = __NSArrayI array3 = 0x102904260 class = __NSArrayM ======== The element is String ======== obj0 = 0x100008220 class = __NSCFConstantString obj0 = 0x100008220 class = __NSCFConstantString obj0 = 0x100008220 class = The __NSCFConstantString ======== element is mutableString ======== obj1 = 0x1028719B0 class = __NSCFString obj1 = 0x1028719B0 class  = __NSCFString obj1 = 0x1028719b0 class = __NSCFStringCopy the code

From printing:

  • Copy of immutable objects of collection classes is a shallow copy
  • MutableCopy is a deep copy
  • Both copy and mutableCopy are shallow copies of elements in the collection

Collection class mutable objects

NSString *str1 = @"hello world"; NSMutableString *str2 = [NSMutableString stringWithString:@"hello world"]; NSMutableArray *array1 = [NSMutableArray arrayWithObjects: str1, str2, nil]; NSMutableArray *array2 = [array1 copy]; NSMutableArray *array3 = [array1 mutableCopy]; NSLog(@"\n array1 = %p class = %@ \n", array1, [array1 class]); NSLog(@"\n array2 = %p class = %@ \n", array2, [array2 class]); NSLog(@"\n array3 = %p class = %@ \n", array3, [array3 class]); NSLog (@ "\ n \ n = = = = = = = = element is mutableString = = = = = = = ="); NSLog(@"\n obj0 = %p class = %@ \n", array1[0], [array1[0] class]); NSLog(@"\n obj0 = %p class = %@ \n", array2[0], [array2[0] class]); NSLog(@"\n obj0 = %p class = %@ \n", array3[0], [array3[0] class]); NSLog(@"\n\n======== element is String ======== "); NSLog(@"\n obj1 = %p class = %@ \n", array1[1], [array1[1] class]); NSLog(@"\n obj1 = %p class = %@ \n", array2[1], [array2[1] class]); NSLog(@"\n obj1 = %p class = %@ \n", array3[1], [array3[1] class]);Copy the code

Output:

2021-05-08 17:40:01.757406+0800 AlgorithmDemo[40202:14563979] array1 = 0x1006046E0 class = __NSArrayM array2 = 0x100604860 class = __NSArrayI array3 = 0x100604890 class = __NSArrayM ======== The element is mutableString ======== obj0 = 0x100008220 class = __NSCFConstantString obj0 = 0x100008220 class = __NSCFConstantString obj0 = 0x100008220 class = The __NSCFConstantString ======== element is String ======== obj1 = 0x100604510 class = __NSCFString obj1 = 0x100604510 class = __NSCFString obj1 = 0x100604510 class = __NSCFStringCopy the code

Conclusion: both mutableCopy and copy of a collection mutable object are deep copies, but the elements in the collection are shallow copies

conclusion

Let’s make a list of non-collection classes

_ copy mutableCopy
NSString Shallow copyReturn the original object Deep copyReturns a new NSString
NSMutableString Deep copyReturns a new NSMutableString Deep copy Returns a new NSMutableString

In a word, only immutable copies of non-collection objects are shallow copies. All others are deep-copy collection classes

_ copy mutableCopy
NSArray Shallow copyElement shallow copy Deep copyElement shallow copy
NSMutableArray Deep copyElement shallow copy Deep copyElement shallow copy

The copy of immutable objects is a shallow copy, while the others are deep copies, and the elements in the collection are shallow copies

It can also be summarized in another way:

  • Copy: Indicates a shallow copy of an immutable object and a deep copy of a mutable object
  • MutableCopy: always a deep copy
  • Elements in a collection object are shallow copies regardless of depth