OC learning --- copying objects, oc --- copying

Source: Internet
Author: User

OC learning --- copying objects, oc --- copying
In the previous article, we talked about how to solve the circular reference problem of objects. However, OC is more inclined to Java. If an object in OC needs to be copied, it needs to implement the Protocol:

<NSCopying>, <NSMutableCopying>

We can see from the name that a protocol is used for immutable objects, and a Protocol applies


First, let's introduce the concept of object copy:

Why is the concept of object copying? Let's look at a scenario: if an object contains another array object, now we generate an object and assign this object to another object, now the problem is that the array objects in these two objects are the same. If the content in this value is modified in one object, the array content in the other object will also be modified, this is equivalent to sharing the array object. Of course, we sometimes don't want this form to appear. At this time, we have copied the object.

Let's look at an example.


I. Copying System Objects

//// Main. m // 30_CopyObject // Created by jiangwei on 14-10-13. // Copyright (c) 2014 jiangwei. all rights reserved. // # import <Foundation/Foundation. h>/***/int main (int argc, const char * argv []) {@ autoreleasepool {// the object can be copied, the following protocols must be implemented: // <NSCopying> and <NSMutableCopying> // The copy method returns an immutable object, the mutableCopy method returns a mutable object/* NSMutableArray * array1 = [NSMutableArray arrayWithObjects: @ "one", @ "two", nil]; NSMu TableArray * array2 = [array1 retain]; // retain only references count + 1, and no new object is created. // The array1 and array2 pointers are the same, point to the same object if (array1 = array2) {NSLog (@ "array1 = array2"); NSLog (@ "array1 reference count: % ld", array1.retainCount );} */NSMutableArray * array1 = [NSMutableArray arrayWithObjects: @ "one", @ "two", nil]; // copy an object, create a new copy object // use the copy method to copy the object. The returned result is an immutable array, but it is declared using a mutable array. However, we are concerned with the pointer content, instead of Type // so the actual type of array2 is not variable type NSMutableArray * array2 = [Array1 copy]; // The array2 count is: 1 because it is a newly created object. // use the mutableCopy method, the returned result is a mutable array // Of course, this method is only useful for those with mutable objects, for other objects, this method has the same effect as the copy method. NSMutableArray * array3 = [array1 mutableCopy]; if (array1! = Array2) {NSLog (@ "array1! = Array2 "); NSLog (@" array1 reference count: % ld ", array1.retainCount); NSLog (@" array2 reference count: % ld ", array2.retainCount );} [array2 release]; [array1 release];} return 0 ;}
We can see that NSMutableArray has a mutableCopy method, so that an array object returned is a copy object.

However, note the following:

Differences between the copy method and the mutableCopy Method

The difference between the two methods is that objects with variable objects and immutable objects have the same effect for objects without such distinction.

[Immutable object copy] is a false copy, which is equivalent to [immutable object retain]

[Immutablecopy is a real copy.



Ii. Deep copy and light copy

There are also deep copy and shortest copies in the copy object.

Shallow copy: only copies the pointer of all attribute objects.

Deep copy: copy the property object content

Let's look at an example:

Person. h

/// Person. h // 31_DeepCopy /// Created by jiangwei on 14-10-13. // Copyright (c) 2014 jiangwei. all rights reserved. // # import <Foundation/Foundation. h> @ interface Person: NSObject <NSCopying> @ property (nonatomic, retain) NSMutableArray * apples; @ property (nonatomic) int age; @ end


Person. m

/// Person. m // 31_DeepCopy /// Created by jiangwei on 14-10-13. // Copyright (c) 2014 jiangwei. all rights reserved. // # import "Person. h "@ implementation Person-(id) copyWithZone :( NSZone *) zone {// create a new copy object // This method will be inherited, so here we still don't need to use // [Person allocWithZone: <# (struct _ NSZone *) #>]; Person * p = [[self class] allocWithZone: zone]; // p. apples = _ apples; // is a pointer value, so the reference count will be + 1 after the light copy/deep copy // copy, and the following p must be release. apples = [_ apples mutableCopy]; p. age = _ age; [p. apples release]; // if we use the-> syntax, we do not need it because we do not use the set method, there is no reference count operation // but we do not use this method // p-> _ apples = [_ apples mutableCopy]; return p;} @ end

We can see that Person implements the NSCopying protocol, and then we need to implement a method: copyWithZone

In this method, we start the copy operation:

One property type in the Person class is array.

Here we need to generate a Person object, copy the attributes, and finally return this object.

Shallow copy: directly copy the array pointer

Deep copy: directly copy the content of the array. Here you can directly use the mutableCopy Method for implementation.


Test class

Main. m

//// Main. m // 31_DeepCopy /// Created by jiangwei on 14-10-13. // Copyright (c) 2014 jiangwei. all rights reserved. // # import <Foundation/Foundation. h> # import "Person. h "// deep copy and light copy // The default value is the light copy int main (int argc, const char * argv []) {@ autoreleasepool {NSMutableArray * array1 = [NSMutableArray arrayWithCapacity: 2]; for (int I = 0; I <2; I ++) {Person * p = [[Person alloc] init]; [array1 addObject: p]; [p release];} // The reference count is 1 for (Person * p in array1) {NSLog (@ "reference count before copying: % ld", p. retainCount); NSLog (@ "pointer before copying: % p", p);} // The reference count is both 2. Because it is a shortest copy, another pointer points to the object, array2 also uses the person // shortest: only copy Object Pointer // deep copy: copy attribute NSArray * array2 = [array1 copy]; for (Person * p in array2) {NSLog (@ "reference count before copying: % ld", p. retainCount); NSLog (@ "pointer before copying: % p", p);} // here, a property in Person is NSMutableArray, but we only assign values, it is not a copy // so it is not a deep copy of Person * p = [[Person alloc] init]; p. apple S = [NSMutableArray arrayWithObjects: @ "iphone", @ "ipad", nil]; p. age = 20; Person * p1 = [p copy]; if (p! = P1) {NSLog (@ "p1.age = % d", p1.age); NSLog (@ "p1.apples = % @", p1.apples);} return 0 ;}


3. Copy strings

//// Main. m // 32_NSStringCopy /// Created by jiangwei on 14-10-13. // Copyright (c) 2014 jiangwei. all rights reserved. // # import <Foundation/Foundation. h> # import "Person. h "// Why does the string use copyint main (int argc, const char * argv []) {@ autoreleasepool {Person * p = [[Person alloc] init]; NSMutableString * name = [NSMutableString stringWithString: @ "jack"]; p. name = name; // the name of a Person has been modified. // If the name of a Person is retain, the name and person object name here are the same string object // after the name is modified, the person name will also be modified, destroys the encapsulation of the person object. // normally, we will use the set method to set the name. // if we use copy, the name will not be changed. [name appendString: @ "-tom"]; // objects that can be copied in the Foundation framework. When we copy an immutable object, // This is equivalent to retain (memory optimization by the system) // If you replace it with the NSString type, there is no copy action, because NSString is immutable // but you can copy it using mutableCopy, mutableCopy is a copy method in the real sense. // mutableCopy is a false copy regardless of the object. // [immutable object copy, equivalent to [immutable object retain] // [immutablecopy is a real copy} return 0 ;}
Here, why do we need to talk about copying strings separately?

Because a string is a special object, we should call its copy method. Because we expect a string to be worth only one point, let's look at the above example:

We use NSMutableString to generate a name and assign it to the person object. When we modify the name content outside, the name attribute value of person should also be modified. Therefore, when copying a String object, we call its copy method.


Summary

This article mainly introduces the concepts and knowledge points of object copy in OC. When operating on objects, we sometimes need to carefully consider whether it is a deep copy or a light copy.




Related Article

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.