Concept
There are two ways to copy objects: Shallow copy and deep copy. As the name implies, shallow copy, not copy the object itself, just copy the pointer to the object; Deep copy copies the entire object memory directly into another memory.
Detailed
It is simpler to say: shallow copy is pointer copy, deep copy is content copy.
A shallow copy of the collection (shallow copy)
There are many ways to shallow copy a collection. When you make a shallow copy, the retain message is sent to the original collection, the reference count plus 1, and the pointer is copied to the new collection.
Example of a shallow copy:
Nsarray *shallowcopyarray =*shallowcopyset =*shallowcopydict = [[Nsdictionary alloc] Initwithdictionary:somedictionary Copyitems:no];
Example of deep copy method one:
// There are two methods for deep copy of a collection. Can be used Initwitharray:copyitems: The second parameter is set to Yes to deep copy, such as:nsdictionary shallowcopydict = [[Nsdictionary alloc] Initwithdictionary:somedictionary Copyitems:yes];
If you copy deep in this way, each object in the collection will receive a copywithzone: message. If the object in the collection follows the Nscopying protocol, the object is deeply copied to the new collection. If an object does not follow the Nscopying protocol and attempts to make a deep copy in this way, an error occurs at run time. Copywithzone: This copy can only provide a single layer of memory copy (One-level-deep copy), rather than a true deep copy.
Examples of deep copy method two:
Nsarray *truedeepcopyarray = [Nskeyedunarchiver unarchiveobjectwithdata:[nskeyedarchiver archivedDataWithRootObject : Oldarray]];
Single-layer deep copy of the collection (One-level-deep copy)
See here, there are alumni asked: If in a multilayer array, the first layer of the content copy, the other layer for pointer copy, this case is a deep copy, or shallow copy? On this, Apple official website document has such a sentence description
is only capable of producing a one-level-deep copy. If you have need a one-level-deepcopy ... true as when you had an array of arrays ...
As can be seen from the text, Apple believes that this duplication is not a true deep copy, but rather it is called a single-layer deep copy (one-level-deep copy). Therefore, the concept of shallow copy, deep copy, and single layer deep copy is differentiated by some people on the Internet.
shallow copy (shallow copy): During a shallow copy operation, the pointer is copied for each layer of the copied object. Deep copy (one-level-deeply copy): In the case of a deep copy operation, at least a layer is a deep copy of the object being copied. Full replication (real-deep copy): In the case of a full copy operation, object replication is for each layer of the replicated object
Of course, these are all conceptual things, and there's no need to dwell on this. As long as the copy operation is known, the pointer or the content is copied.
Copy and Mutablecopy Methods for system objects
Whether it is a collection class object or a non-collection class object, the following guidelines are followed when you receive copy and Mutablecopy messages:
- Copy returns the Imutable object, so if the Mutable object interface is used for the copy return value, it will be crash;
- Mutablecopy returns the Mutable object;
The following is a detailed description of the copy and Mutablecopy methods for non-collection class objects and collection class objects
1. Copy and mutablecopy of non-collection objects
System non-Collection class object refers to NSString, nsnumber ... Objects such as the. Let's look at an example of a non-aggregate class immutable object copy.
1 NSString *string@ "origin"; 2 NSString *stringcopy = [string copy]; 3 nsmutablestring *stringmcopy = [string mutablecopy];
By looking at the memory, you can see that the address of stringcopy and string is the same, the pointer is copied, and the address of stringmcopy is not the same as the string, the content is copied;
Look again at the Mutable object copy Example
1Nsmutablestring *string= [Nsmutablestring stringwithstring:@"Origin"];2 //Copy3NSString *stringcopy = [stringcopy];4nsmutablestring *mstringcopy = [stringcopy];5nsmutablestring *stringmcopy = [stringMutablecopy];6 //Change value7[Mstringcopy appendString:@"mm"];//Crash8[stringAppendString:@"origion!"];9[Stringmcopy appendString:@"!!"];
Running the above code is crash on line 7th, because the object returned by copy is the immutable object. Note the 7th line after the run, look at the memory, found that the string, Stringcopy, Mstringcopy, stringmcopy four objects memory address is different, indicating that this is a copy of the content.
With two examples, we can draw the conclusion that:
1 In a non-collection class object: Copy the Immutable object, copy the pointer, copy the contents of the mutablecopy operation, and copy and mutablecopy the Mutable object as content replication. The code is simply represented as follows:23 // Shallow copy 4 // deep copy 5 // deep copy 6 // deep copy
2. Copy and Mutablecopy of the collection class object
The collection class object refers to Nsarray, Nsdictionary, Nsset ... Objects such as the. Here's an example of a collection class immutable object using Copy and Mutablecopy:
1 Nsarray *array = @[@[@"a"@ "b"], @[@ "C "@"d"]; 2 Nsarray *copyarray = [array copy]; 3 Nsmutablearray *mcopyarray = [array mutablecopy];
Viewing the content, you can see that the Copyarray and array addresses are the same, and the addresses of the Mcopyarray and array are different. The copy operation has a copy of the pointer, and mutablecopy copies the content. However, it should be emphasized that the copy of the content here is simply a copy of the array object, and the elements inside the array collection are still pointer copies. This is quite similar to the copy of the non-collection immutable object above, so will the copy of the Mutable object be similar? Let's go down and look at examples of mutable object copies:
1 Nsmutablearray *array = [Nsmutablearray arraywithobjects:[nsmutablestring stringwithstring:@ "a "],@"b",@"C", nil]; 2 Nsarray *copyarray = [array copy]; 3 Nsmutablearray *mcopyarray = [array mutablecopy];
Look at the memory, as we expected, Copyarray, Mcopyarray, and array memory addresses are different, indicating that Copyarray, Mcopyarray have a content copy of the array. Again, we can draw the conclusion that:
1 In the collection class object, copy the immutable object, which is the pointer copy, the mutablecopy is the content copy, and the copy and Mutablecopy of the Mutable object are content replication. However: the content copy of the collection object is limited to the object itself, and the object element is still a pointer copy. The code is simply represented as follows:23 // Shallow copy 4 // single layer deep copy 5 // single layer deep copy 6 // single layer deep copy
This code conclusion is very similar to the non-collection class.
At this time, is not someone to ask, if you want to copy elements of the collection object what to do? Students with this question may wish to look back at the deep copy of the collection .
Well, deep copy and shallow copy are here.
In the process of collecting data, we can find a point that is likely to make a mistake.
1 @" string " ; 2 @" newstring ";
The above code, after executing the second line of code, the memory address changed. At first glance, it was a bit of an accident. According to the C language experience, after initializing a string, the first address of the string is determined, and no matter how the string content is modified, the address will not change. But the second line here is not a re-assignment of the memory address pointed to by STR, because the left str of the assignment operator is a pointer, which means that the memory address is modified here.
So the second line should understand this: "Newstirng" as a new object, the memory address of this object is assigned to Str.
I like the next two ways to view memory address
1 p STR Prints the memory address and object contents of the object itself 2 (LLDB) p str 3 (NSString *) $00x000000010c913680@ "a"4 5 po &STR Prints the address where the pointer to the reference object is located 6 (LLDB) PO &str7 0X00007FFF532FB6C0
Reference documents
- [1] Apple collections programming Topics:copying Collections
- [2] deep copy of IPhone Dev:ios development and light copy (mutablecopy and copy)
- [3] Blog:copy and Mutablecopy
Original address: https://www.zybuluo.com/MicroCai/note/50592
Deep copy and shallow copy of iOS