Iphone copy and mutablecopy

Source: Internet
Author: User

From: http://oasku.com /? Q-104.html

 

First, start with copy. In short, the purpose of copy is to generate a new instance and assign values to all its members based on the original Instance. For non-pointer-type members, such as BOOL, int, float, such values can be directly assigned. However, for pointer-type data, such as objects used in Objc, There is Deep Copy and Shallow CopyDifference-this is basically the same as in C ++: Yes Generate a new member object, Or Point to the same Member object.

After resolving this, let's look at the implementation method of Copy in Objetive-C. If you want to call the copy method of an object, this object must followNSCopying Protocol. This Protocol specifies a method:-(Id) copyWithZone :( NSZone *) zoneWe implement this method to provide the object with the copy function. For many existing classes, such as NSString, NSDictionary ,... This method has been implemented. Assume that we have customized a class and need to provide the copy function for this class, we need to write the CopyWithZone method by ourselves: Example:

This is a custom class:
@ Interface Product: NSObject <NSCopying>
{
NSString * productName;
Float price;
Id delegate;
}

@ End

Then we need to implement the copyWithZone method in NSCopying in the Product class:
-(Id) copyWithZone :( NSZone *) zone
{
Product * copy = [[self class] allocWithZone: zone]
InitWithProductName: [self productName]
Price: [self price]; // note that here we use the class allocWithZone method to create a copy. Here we assume that there is an initWithProductName: price: initialization method in the Product class. After this call, a copy of the Product is obtained, and both the name and price have been set.

[Copy setDelegate: [self delegate]; // set delegate here.

Return copy; // returns the copy.
}

In this case, if we have a product instance, assume it is product1, and then call Product * product2 = [product1 copy];
We will use the copyWithZone method we wrote above to create a copy of product1 and assign it to product2.

Here, the delegate member in the above method is used as an example to explain deep copy and shallow copy:

In the copyWithZone method, we get a new product instance, but delegate is an object. Therefore, in the copy, we can choose to create a new delegate object (deep copy ), or point to the same delegate (shallow copy ). This depends on the setDelegate: Method in the Product class. You can choose to copy when setDelegate, or let them all point to the same object (but retain is required for the reason, you can think for yourself). Of course, simple assign can also be used in some cases.

Suppose there is setDelegate: Method in the Product class, or the property with delegate:
-(Void) setDelegate: (id) aDelegate
{
[Delegate release];
Delegate = [delegate copy];
}

This is a deep copy, because a copy of the delegate is obtained using the delegate copy method. The implementation of the copyWithZone method of delegate depends on how to obtain a copy of delegate. That is to say, copy is always in a "recursive" form. From top to bottom, we can consider it layer by layer.

-(Void) setDelegate: (id) aDelegate
{
[Delegate release];
Delegate = [aDelegate retain];
}
After this operation, the delegate and aDelegate are the same object, but for memory management requirements, we call retain to add the reference count to one. Of course, if you do not need it, you can also directly assign values (assign ):
-(Void) setDelegate: (id) aDelegate
{
Delegate = aDelegate
}

You can implement this example by yourself, and then use log to create a dozen memories. This structure is very clear.

Next, let's talk about mutable copy and immutable copy ):
The concepts of mutable and immutable have been learned through the differences between NSDictionary and NSMutableDictionary.
In general, if one of our classes needs to treat these two features differently-at the same time, it provides the creation of both a mutable copy and an immutable copy, generally, immutable copies are returned in the copyWithZone method specified by the NSCopying protocol, while the mutableCopyWithZone method of NSMutableCopying. Call the copy and mutableCopy methods of the object to obtain the copy.

For example:
The NSDictionary class has already followed the NSCopying and NSMutableCopy protocols. That is to say, we can call its copy and mutableCopy to obtain immutable and mutable copies. The program is as follows:

NSDictionary * testDict = [[NSDictionary alloc] initWithObjectsAndKeys: @ "hello", @ "test", nil];
NSDictionary * destDict = [testDict copy];
NSLog (@ "test Dict: % p, retain Count: % d \ ndest Dict: % p, retain Count: % d", testDict, [testDict retainCount], destDict, [destDict retainCount]);

The running result on my machine is:
Test Dict: 0x11f220, retain Count: 2
Dest Dict: 0x11f220, retain Count: 2
It seems that two dict points to the same memory area, but retainCount adds 1. This should be understood, because we need to return an immutable object using the NSCopying method. And the original testDict is also immutable, so the "copy" here does not make much sense (this is like when using string constants, the system will optimize for us, if multiple strings are declared, but they are constants and the content is equal, then the system will apply for only one space for us. This is the same ). Since it cannot be changed, you can point to the same space. There is no difference between copy and retain.

We use the copyWithZone method to return immutable objects, regardless of whether the original object is variable or immutable. Let's take a look at the following code:
NSMutableDictionary * testDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys: @ "hello", @ "test", nil];
NSMutableDictionary * destDict = [testDict copy];
NSLog (@ "test Dict: % p, retain count: % d \ ndest Dict: % p, retain count: % d", testDict, [testDict retainCount], destDict, [destDict retainCount]);
[DestDict setObject: @ "what" forKey: @ "test2"];

NSMutableDictionary is variable. The result of this code running on my machine is:
Test Dict: 0x20dcc0, retain count: 1
Dest Dict: 0x209120, retain count: 1
* **-[NSCFDictionary setObject: forKey:]: mutating method sent to immutable object
We can see that because we have called the copy method of the variable object, this is not the same as in the previous example, just retain. Here, test dict and dest Dict are already two objects. However, the copyWithZone method returns an immutable object. Therefore, an error occurs in the subsequent setObject: forKey: method.

Now, it will be OK.

NSMutableDictionary * testDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys: @ "hello", @ "test", nil];
NSMutableDictionary * destDict = [testDict mutableCopy];
NSLog (@ "test Dict: % p, retain count: % d \ ndest Dict: % p, retain count: % d", testDict, [testDict retainCount], destDict, [destDict retainCount]);
[DestDict setObject: @ "what" forKey: @ "test2"];
NSLog (@ "destDict: % @", destDict );
The running result is:
Test Dict: 0x123550, retain count: 1
Dest Dict: 0x10a460, retain count: 1

DestDict :{
Test = hello;
Test2 = what;
Because we use mutableCopy to get a mutable copy.

Note: All classes provided by the system that support both NSCopying and NSMutableCopying are supported.
Copy method to obtain an immutable object, regardless of whether the previous object is variable or immutable.
MutableCopy method, the result is a mutable object, no matter whether it is variable or not.

 

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.