Shallow copy
Shallow copy is the copy of the memory address, so that the target object pointer and the source object point to the same memory space, when the memory is destroyed At that time, several pointers to this piece of memory need to be redefined before they can be used, or they will become wild pointers.
Shallow copy means copy pointing to the original object The pointer to make the reference count of the original object +1, which can be understood as creating a new pointer to the original object, but not creating a brand new object.
deep copy
Deep copy refers to the specific content of the copy object, and the memory address is allocated independently. After the copy is over, although the two objects are stored The value is the same, but the memory address is different, and the two objects do not affect each other or interfere with each other.
Deep copy means copy out and original Only a new object with the same value but a completely different memory address has nothing to do with the original object after creation.
Summary
Deep copy is content copy, shallow copy is pointer copy. The essential difference lies in:
- Whether to open a new memory address
- Whether it affects the reference count of the memory address
Case analysis
In iOS, deep copy and shallow copy are more complicated, involving copy and mutableCopy of container and non-container, mutable and immutable objects. The following examples are used to analyze one by one:
copy and mutableCopy of non-collection objects
immutable object NSString
1 |
-(void) noMutableNSStringTest |
Print result:
2017-07-20 18:02:10.642 beck.wang[1306 :169414] str1:0x106abdbd0-test001 |
Analysis: The address of str1 and str2 is the same and different from the address of str3. The copy of NSString is a shallow copy, and The object returned by copy is an immutable object; mutableCopy is a deep copy.
Variable object NSMutableString
< pre>1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
- (void) mutableNSStringTest |
Print results:
< pre>1 2 3 |
2017-07-20 18:14:35.789 beck.wang[1433:180881] mstr1:0x610000075e40-test002 |
Analysis: The addresses of mstr1, mstr2, and mstr3 are all different. Both NSMutableString object copy and mutableCopy are deep copies. And the object returned by copy is an immutable object.
copy and mutableCopy of collection objects
immutable object NSArray
1 |
- (void) mutableNSArrayTest |
Print results:
1 |
2017-07-20 18:33 :53.707 beck.wang[1502:194476] arry1:0x60800003b480-( |
Analysis: The addresses of arry1 and arry2 are the same, but the addresses of arr3 are different. The copy of NSArray is a shallow copy, and the object returned by copy is an immutable object; mutableCopy is a deep copy.
Variable Object NSMutableArray
< pre>1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
- (void) NSMutableArrayTest |
Print results:
1 |
2017-07-20 18:55:43.243 beck.wang[1577:204641] marry1:0x600000048d60-( |
Analysis: marry1, The addresses of marry2 and marr3 are different. Both NSMutableArray object copy and mutableCopy are deep copies, and the objects returned by copy are immutable objects.
Special attention is paid: For collection-like mutable objects, deep copy is not strictly a deep copy, it can only be regarded as a single-layer deep copy< /strong>, that is, although the memory address is newly opened, but the value stored in the memory (that is, the element in the array is still the previous array element value, and there is no other copy), this is called single-level deep copy.
Example:
1 |
< span class="line">-(void)singleNSMutableArrayTest |
Print results:
1 |
|
Analysis: Before modifying the original value, marry1, The addresses of marry2 and marr3 are not the same. Obviously copy and mutableCopy are both deep copies, but from the printed results after modifying the original value, the deep copy here is only a single-layer deep copy: the memory address is newly opened, but the value in the array The value still points to the original array, so that after the original value is modified, the values in marry2 and marr3 are all modified. In addition, it is obvious from the printed array element addresses that the array element addresses of marry1, marry, and marr3 are exactly the same before and after the modification, which further proves this point.
Expanded thinking: complete deep copy of collection object
For collection objects, deep copy is only a single deep copy , Is there a way to achieve deep copy of each layer? The answer is yes, currently we can do this:
Archive and Unzip Dafa
1 |
- (void) deplyFullCopy |
Print results:
1 |
2017-07-20 20:04 :38.726 beck.wang[1833:242158] marry1:0x600000048a00-( |
-(instancetype)initWithArray:(NSArray *)array copyItems:(BOOL)flag;
1 |
- (void) deplyFullCopy2 |
Print result:
1 |
2017- 07-20 20:08:04.201 beck.wang[1868:246161] marry1:0x610000050320-( |
Guidelines
- No1: Both copy and mutableCopy methods of mutable objects It is a deep copy (the distinction is between a complete deep copy and a single-layer deep copy).
- No2: The copy method of immutable objects is a shallow copy, and the mutableCopy method is a deep copy.
- No3: The objects returned by the copy method are immutable objects.
Other Statements
In the ios development process, there are two concepts of object and container. Object copy is shallow copy, and mutable copy is deep copy. The container also refers to the above method, but you need to remember that the copy of the container containing the object, whether you use copy or mutablecopy, will be a shallow copy. If you want to achieve deep copy of an object, you must provide a copy method yourself. For the method provided by yourself, see the following points of attention.
As mentioned above, the copy of the container is only a single deep copy.
Practical thinking and application
Case
@property (nonatomic,copy) NSString * in B str; is to prevent the A controller, when calling the Str of the B controller, pass in a variable string
If the input is a variable string, use the Copy attribute to make a deep copy change Immutable
If the incoming string is immutable, using the Copy attribute will make a shallow copy, that is, the copy pointer points to the content
If you use Strong, if If the variable character string of controller A changes, the character string in controller B will be affected and change accordingly
Think
【? ? ? ? ? Therefore, in the iOS properties, Strong and retain types will make the reference count +1, and when copying immutable objects, the reference count will be +1 and the content will not change, so it can be visually understood as a shallow copy].
Don’t confuse the reference count with the deep copy, because the deep copy, in any case, the reference count will be +1, you can’t say that the attribute declares Strong, it means that a shallow copy or a deep copy is performed, because Strong If this is the case, there is no operation of copying the pointer or copying the content at all.