Objective-C memory management (I) golden rule understanding

Source: Internet
Author: User

I. golden rules for memory management:

The basic rule to Apple is everything thatincreases the reference counter with alloc, [mutable] Copy [withzone:] Or retainis in charge of the corresponding [auto] Release.

If an object uses alloc, [mutable] Copy, retain, you must use the corresponding release or autonrelease

Ii. Memory Management type classification

Basic type and C language type: for example:

Int, short, Char, struct, Enum, union, and Other Types

OC type: Any object inherited from nsobject belongs to OC type.

The memory management we talk about is actually the memory management for the OC type, it does not work for the basic data type and C language type.

Iii. Insufficient C and C ++ Memory Management

As shown above, another three references point to this memory. When any one calls the Free Method to release the memory, and the other references continue to use this memory without knowing it, the problem may occur. Who will release the memory? This is the chaos in memory management between C and C ++.

Iv. Structure of OC objects in memory

The structure of all oc-type objects is as follows. This object contains its own variables and methods, and there is a reference count containing retaincount.

Each OC object has a four-byte retaincount counter. The number of referenced objects. If the count is 0, the object is actually released.

 


 

Rules:

1. The reference counter is implemented in the objective-C class. The object knows the number of times it is referenced.

2. the counter of the initial object is 1.

3. If you want to reference an object, you can send a retain message to the object, so that the counter of the object is added with 1

4. If you do not need to reference an object, you can send a release message to the object so that the object counter is reduced by 1.

5. When the counter is reduced to 0, the dealloc function of the object is automatically called, and the object will release the memory.

6. Objects whose counter is 0 cannot use release or other methods.

V. Examples

For example, there is an engine and a car, and a car contains an instance variable of the engine, a setter and a getter method. The details are as follows:

#import "Car.h"@implementation Car-(void)setEngine:(Engine*) engine{     _engine=engine;}-(Engine*)engine{    return _engine;}-(void)dealloc{    NSLog(@"Car is dealloc");    [super dealloc];}@end

The above is a simple class. When there is a problem with this writing, it needs to be improved step by step.

Step 1:

First use it to check the problem. Use the following in the main method:

// First create an engine * engine1 = [[engine alloc] init]; [engine1 setid: 1]; // create a car, set car * car = [[Car alloc] init]; // retaincount = 1 [Car setengine: engine1];/* Analysis: Here, now there are two references pointing to this engine object, _ engine in engine1 and car, but the reference count of this engine object is still 1, because retain is not used in the set method. No matter which reference calls release, the other reference will point to a piece of released memory, and an error will certainly occur. Therefore, the set method must be improved. */

Step 2 improvement:

Setter Method Improvement

-(Void) setengine :( engine *) engine {_ engine = [engine retain]; // a reference is added, retaincount + 1}

Use it in main.

// First create an engine * engine1 = [[engine alloc] init]; [engine1 setid: 1]; // create a car, set car * car = [[Car alloc] init]; // retaincount = 1 [Car setengine: engine1]; // retaincount = 2 because retain is used, so retaincount = 2, // assume there is another engine * engine2 = [[engine alloc] init]; [engine2 setid: 2]; // This car needs another engine, naturally, you have to call the settr method [Car setengine: engine2];/* Analysis: here, the car has changed to an engine, then, the _ engine does not point to the memory of the engine1 object. Instead, it is replaced with engine2, which means that the engine1 object points to There is only one reference, but its retaincount is two, which is the problem. So we still need to improve */

Step 3 improvement:

-(Void) setengine :( engine *) engine {[_ engine release]; // release before setting, the previous reference release is automatically removed _ engine = [engine retain]; // a reference is added, retaincount + 1}

And then use it in main '.

// First create an engine * engine1 = [[engine alloc] init]; [engine1 setid: 1]; // create a car, set car * car = [[Car alloc] init]; // retaincount = 1 [Car setengine: engine1]; // retaincount = 2 because retain is used, so retaincount = 2, // if an error occurs, set engine1 [Car setengine: engine1];/* Analysis: Then, call the setter method again, this is a meaningless operation and a waste of resources. Therefore, you must add a judgment between settings */

Step 4 improvement:

-(Void) setengine :( engine *) engine {If (_ engine! = Engine) {// determine whether to repeatedly set [_ engine release]; // release before setting, then when setting, the previous reference release is automatically removed _ engine = [engine retain]; // a reference is added, retaincount + 1 }}

Step 5:

Now the setter method is basically no problem, so when we want to release a car object, we must also release the _ engine reference in it. Therefore, the dealloc method of the car to be rewritten.

-(Void) dealloc {[_ engine release]; // when releasing a car, release its reference to the engine [Super dealloc];}

This is not the best release method. The following method is better.

-(Void) dealloc {[_ engine setengine: Nil]; // when the car is released, set setengine to nil, which not only release but also points to nil, no error occurs even if a call is mistakenly performed. [Super dealloc];}

Therefore, to sum up, the final method in the setter method is

-(Void) setengine :( engine *) engine {If (_ engine! = Engine) {// determine whether to repeatedly set [_ engine release]; // release before setting, then when setting, the previous reference release is automatically removed _ engine = [engine retain]; // a reference is added, retaincount + 1 }}


The statement in the dealloc method is as follows:

-(Void) dealloc {[_ engine setengine: Nil]; // when the car is released, set setengine to nil, which not only release but also points to nil, no error occurs even if a call is mistakenly performed. [Super dealloc];}


6. setter syntax keywords in property

There are three keywords in the property to define the syntax for expanding the setter method, assgin (default), retain, copy. Of course, these three keywords are mutually exclusive.

1. Writing assgin to expand stter

-(void)setEngine:(Engine*) engine{     _engine=engine;}

2. Retain Expansion

-(Void) setengine :( engine *) engine {If (_ engine! = Engine) {// determine whether to repeatedly set [_ engine release]; // release before setting, then when setting, the previous reference release is automatically removed _ engine = [engine retain]; // a reference is added, retaincount + 1 }}

3. Copy Expansion

-(Void) setengine :( engine *) engine {If (_ engine! = Engine) {// determine whether to repeatedly set [_ engine release]; // release before setting, then when setting, the previous reference release is automatically removed _ engine = [engine copy]; // a reference is added, retaincount + 1 }}

For the copy attribute, the object defined with the copy attribute must comply with the nscopying protocol, and you must implement the-(ID) copywithzone :( nszone *) zone method.

We can see that the use of retain is exactly the same as the above example, so we can use the property and its retain to replace the previous statement.

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.