Objective-c memory Management (a) understanding of the golden rule

Source: Internet
Author: User

First, memory management Golden rule:

The basic rule to Apple are 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, then you must use the appropriate release or autonrelease

Second, memory management type classification

Types of basic types and C languages: for example:

Int,short,char,struct,enum,union and other types

OC Type: Any type that inherits from the NSObject object belongs to OC.

The memory management We talk about is actually memory management of OC type, which does not work for basic data types and C language types.

Three, C and C + + memory management deficiencies

As above, 3 references point to this piece of memory, any one calls the free method to release the memory, while the rest of the references continue to use this memory without knowing, there is a problem. When to release this memory, this is the confusion of C and C + + in memory management.

IV. structure of OC objects in memory

The structure of all OC-type objects is as follows: The memory of this object contains its own variables and methods, and a reference count containing Retaincount.

Each OC object has a 4-byte retaincount counter. Represents the count of the current object being referenced. If the count is 0, then you really want to release the object.


Rules:

1, the Objective-c class implements the reference counter, the object knows its current number of references

2, the initial object counter is 1

3, if you need to reference the object, you can send an retain message to the object, so that the object's counter is added 1

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

5, when the counter is reduced to 0, automatically call the object's Dealloc function, the object will free memory

6. Objects with counter 0 can no longer use release and other methods

V. Illustrative examples

For example, there is an engine, there is a car class car,car inside there is a song engine instance variables, a setter and getter method. Specific as follows

[Plain]View Plaincopy
    1. #import "Car.h"
    2. @implementation Car
    3. -(void) Setengine: (engine*) Engine
    4. {
    5. _engine=engine;
    6. }
    7. -(engine*) Engine
    8. {
    9. return _engine;
    10. }
    11. -(void) dealloc
    12. {
    13. NSLog (@ "Car is Dealloc");
    14. [Super Dealloc];
    15. }
    16. @end



The above is a simple class, and when it is problematic to write this, it requires a step-by-step improvement.

The first step is to improve:

Use it first to see where the problem is, and in the main method, use the following:

[Plain]View Plaincopy
    1. Create an engine first
    2. engine* Engine1=[[engine Alloc]init];
    3. [Engine1 setid:1];
    4. In creating a car, set the engine of the car
    5. car* Car=[[car Alloc]init];//retaincount=1
    6. [Car setengine:engine1];
    7. /* Analysis: Here, there are now two references to this engine object, Engine1 and car _engine, but this engine object has a reference count of 1, because the
    8. In the Set method, retain is not used. Then no matter which reference calls release, then the other reference will point to a piece of freed memory, then certainly
    9. An error will occur. Therefore, it needs to be improved in the Set method. */


The second step is to improve:

Setter Method Improvement

[Plain]View Plaincopy
    1. -(void) Setengine: (engine*) Engine
    2. {
    3. _engine=[engine retain];//One more quote, retaincount+1
    4. }

And then use it in main.

[Plain]View Plaincopy
  1. Create an engine first
  2. engine* Engine1=[[engine Alloc]init];
  3. [Engine1 setid:1];
  4. In creating a car, set the engine of the car
  5. car* Car=[[car Alloc]init];//retaincount=1
  6. [Car setengine:engine1];//retaincount=2, because the use of retain, so retaincount=2,
  7. Suppose there's another engine.
  8. engine* Engine2=[[engine Alloc]init];
  9. [Engine2 Setid:2];
  10. This car is going to change an engine, and it's natural to call the Settr method
  11. [Car setengine:engine2];
  12. /* Analysis: Here, the car changed an engine, then its _engine is not pointing to engine1 of which object's memory, but instead of the engine2, that is, which object of Engine1 point to the memory of the reference only one
  13. But its retaincount is two, and that's where the problem lies. So we still need to improve */


The third step is to improve:

[Plain]View Plaincopy
    1. -(void) Setengine: (engine*) Engine
    2. {
    3. [_engine release];//before setting, the first release, then in the setting, will automatically put the previous reference to release
    4. _engine=[engine retain];//One more quote, retaincount+1
    5. }

And then use it in main '

[Plain]View Plaincopy
    1. Create an engine first
    2. engine* Engine1=[[engine Alloc]init];
    3. [Engine1 setid:1];
    4. In creating a car, set the engine of the car
    5. car* Car=[[car Alloc]init];//retaincount=1
    6. [Car setengine:engine1];//retaincount=2, because the use of retain, so retaincount=2,
    7. If you make a mistake, you set a engine1
    8. [Car setengine:engine1];
    9. /* Analysis: Then, recall the setter method again, this is simply meaningless operation, wasting resources, so you have to add a judgment between the settings */


Fourth Step improvement:

[Plain]View Plaincopy
    1. -(void) Setengine: (engine*) Engine
    2. {
    3. if (_engine!=engine) {//Determine if the settings are repeated
    4. [_engine release];//before setting, the first release, then in the setting, will automatically put the previous reference to release
    5. _engine=[engine retain];//One more quote, retaincount+1
    6. }
    7. }


Fifth Step:

Now the setter method is basically no problem, then when we want to release a car object, we must also release the _engine inside it, so, to rewrite car Dealloc method.

[Plain]View Plaincopy
    1. -(void) dealloc
    2. {
    3. [_engine release]; When the car is released, release its reference to the engine
    4. [Super Dealloc];
    5. }


This is not the best way to release, the following method is better

[Plain]View Plaincopy
    1. -(void) dealloc
    2. {
    3. [_engine Setengine:nil]; When the car is released, the Setengine is set to nil, which not only releases it, but also points to nil, even if the call is wrong.
    4. [Super Dealloc];
    5. }



So, in summary, the final notation in the setter method is

[Plain]View Plaincopy
    1. <span style= "color: #CC66CC;" >-(void) Setengine: (engine*) Engine
    2. {
    3. if (_engine!=engine) {//Determine if the settings are repeated
    4. [_engine release];//before setting, the first release, then in the setting, will automatically put the previous reference to release
    5. _engine=[engine retain];//One more quote, retaincount+1
    6. }
    7. }</span>


Then the notation in the Dealloc method is:

[Plain]View Plaincopy
    1. <span style= "color: #CC66CC;" >-(void) dealloc
    2. {
    3. [_engine Setengine:nil]; When the car is released, the Setengine is set to nil, which not only releases it, but also points to nil, even if the call is wrong.
    4. [Super Dealloc];
    5. }</span>

The setter syntax keywords in the property

There are three keywords in the property attribute defined about the syntax in the unwind setter method, Assgin (default), Retain,copy. Of course, these three keywords are mutually exclusive.

1, Assgin to expand the wording of Stter

[Plain]View Plaincopy
    1. -(void) Setengine: (engine*) Engine
    2. {
    3. _engine=engine;
    4. }

2, retain expansion of the wording

[Plain]View Plaincopy
    1. -(void) Setengine: (engine*) Engine
    2. {
    3. if (_engine!=engine) {//Determine if the settings are repeated
    4. [_engine release];//before setting, the first release, then in the setting, will automatically put the previous reference to release
    5. _engine=[engine retain];//One more quote, retaincount+1
    6. }
    7. }

3, copy expansion of the wording

[Plain]View Plaincopy
    1. -(void) Setengine: (engine*) Engine
    2. {
    3. if (_engine!=engine) {//Determine if the settings are repeated
    4. [_engine release];//before setting, the first release, then in the setting, will automatically put the previous reference to release
    5. _engine=[engine copy];//One more quote, retaincount+1
    6. }
    7. }

For the Copy property to be primary, the object defined with the Copy property must conform to the Nscopying protocol, and you must also implement the-(ID) Copywithzone: (nszone*) zone for the method.

As you can see, using retain is exactly the same as the example we have above, so we can use the property and its retain instead of the previous notation.

Objective-c memory Management (a) understanding of the golden rule

Objective-c memory Management (a) understanding of the golden rule

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.