Deep copy and shallow copy of IOS collection

Source: Internet
Author: User

Transferred from: https://www.zybuluo.com/MicroCai/note/50592

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.

A picture of the

It is simpler to say: Shallow copy is pointer copy, deep copy is content copy.

Shallow copy of 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.

Now let's look at some examples of shallow replication:

  1. NSArray *shallowCopyArray = [someArray copyWithZone:nil];
  2. NSSet *shallowCopySet = [NSSet mutableCopyWithZone:nil];
  3. NSDictionary *shallowCopyDict = [[NSDictionary alloc] initWithDictionary:someDictionary copyItems:NO];
Deep copy of the collection

There are two methods for deep copy of a collection. You can use Initwitharray:copyitems: Set the second parameter to Yes to deep copy, as

    1. 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.

The second method is to archive the collection (archive) and then extract the files (unarchive), such as:

    1. 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

This kind of copy are only capable of producing a one-level-deep copy. If you are only need a one-level-deep copy ...

If you need a true deep copy, such as when you have 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-deep copy): In a deep copy operation, at least one layer of the copied object is a deep copy.
  • Full replication (real-deep copy): During 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 = @
    2. nsstring *= [string
    3. nsmutablestring *= [string

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

  1. NSMutableString *string = [NSMutableString stringWithString: @"origin"];
  2. //copy
  3. NSString *stringCopy = [string copy];
  4. NSMutableString *mStringCopy = [string copy];
  5. NSMutableString *stringMCopy = [string mutableCopy];
  6. //change value
  7. [mStringCopy appendString:@"mm"]; //crash
  8. [string appendString:@" 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:

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:

  • [Immutableobject Copy]//Shallow copy
  • [Immutableobject mutablecopy]//Deep copy
  • [Mutableobject Copy]//Deep copy
  • [Mutableobject mutablecopy]//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:

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:

  • [Immutableobject Copy]//Shallow copy
  • [Immutableobject mutablecopy]//single layer deep copy
  • [Mutableobject Copy]//single layer deep copy
  • [Mutableobject mutablecopy]//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. NSString *str = @"string";
    2. str = @"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

    • p strPrints the memory address and object contents of the object itself
    1. (lldb) p str
    2. (NSString *) $0 = 0x000000010c913680 @"a"
    • po &strThe address where the pointer to the referenced object is printed
    1. (lldb) po &str
    2. 0x00007fff532fb6c0

Reference documents

[1] Apple collections programming Topics:copying Collections
[2] deep copy of IPhone Dev:ios development and light copy (Mutablecopy and copy) (blog may be flawed, children's shoes carefully read personally verified)
[3] Blog:copy and Mutablecopy

Deep copy and shallow copy of IOS collection

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.