[Objective-C] Reference counting

1. Basic concepts:

As the name suggests, Automatic Reference Counting (ARC) refers to the technology of automatically counting references in memory management. The following is excerpted from Apple’s official description:

The Automatic ReferenceCounting (ARC) mechanism is used in Objective-C to let the compiler perform memory management. Setting ARC to a valid state in the new generation of Apple LLVM compiler eliminates the need to type retain or release code again. This reduces the risk of program crashes, memory leaks, etc., and greatly reduces the workload of developing programs. The compiler has complete knowledge of the target objects and can immediately free those objects that are no longer used. As a result, applications will be predictable, run smoothly, and be significantly faster.

When the reference count of an object is greater than 0, it means that the object is held and cannot be
Release, when the reference count reaches 0, it means that the object needs to be released.

Reference Count

The principle of reference counting: Reference counting can effectively manage the life cycle of an object. When we create a new object, its reference count (the memory block where the object is located) is 1. When a new pointer points to this object , we increase its reference count by 1. When a pointer no longer points to this address, we decrease its application count by 1. When the reference count of the object becomes 0, it means that this memory is no longer pointed by any pointer. At this time, the system The object will be destroyed and the memory will be reclaimed. In order to achieve the purpose of managing memory.

for example:
Suppose there is only one lighting fixture in the office. People who enter the office at work need lighting, so they should turn on the lights. For people who leave the office after get off work, they no longer need lighting, so they need to turn off the lights. The lighting equipment in the office is equivalent to the object, and the number of people in the office is equivalent to the reference counter of the object. When a person comes to the office, the reference counter increases by one, and when a person leaves, the reference counter decreases by one. As long as there is someone in the office, the light must be turned on. No You can turn it off when you are a human, which is equivalent to releasing the object.

Actions performed on lighting devices Actions performed on Objective-C objects
Turn on the light Generate object
Need lighting Hold object
No lighting required Release the object
Turn off the light Discard the object

2. Ways of thinking about memory management:

Object operation O bje ctive-C method
Generate and Hold the object alloc/new/copy/mutableCopy and other methods
Hold the object retain method
Release object release method
Discard object dealloc method

1. Objects generated by yourself are held by yourself

Using a method name starting with the following means that the object you generate is only owned by you:

  • alloc
  • new
  • сору
  • mutableCopy
    Example:
id obj = [[NSObject alloc] init];

id obj = [NSObject new];

Among them, [[NSObject alloc] init] and [NSObject new] are completely consistent.

In addition, according to the above “use method names starting with the following names”, the following names also mean that objects are generated and held by themselves.

  • allocMyObject
  • newThatObject
  • copyThis
  • mutableCopyYourObject

But for the following names, even if they start with alloc/new/copy/mutableCopy names, they do not belong to the same category of methods.

  • allocate
  • newer
  • copying
  • mutableCopyed

2. You can also hold objects that are not generated by yourself

The object obtained by methods other than the above items, that is, the object obtained by methods other than alloc/new/copy/mutableCopy, is not the holder of the object because it is not generated and held by itself.

//Get objects not generated and held by yourself

id obj = [NSMutableArray array]:

//The obtained object exists, but it does not hold the object itself

[obj retainl;

//Hold the object yourself

As can be seen from the above examples, through the retain method, the objects generated by others that are not owned by oneself become owned by oneself, just like the objects generated and held by the alloc/new/copy/mutableCopy method.

3. Release the object you hold when you no longer need it

Once the object held by itself is no longer needed, the holder is obliged to release the object. Release using the release method.

//Generate and hold the object yourself
id obj = [INSObject alloc] init];

[obj releasel];

//Release the object. The pointer to the object is still retained in the variable obj and seems to be accessible, but the object is absolutely inaccessible once it is released.

In this way, the object generated and held by itself using the alloc method is released through the release method.
Objects generated by oneself but not held by oneself can also be released by using the release method if they are held by oneself using the retain method.

//The obtained object exists, but it does not hold the object.
id obj = [NSMutableArray array];

//Hold the object yourself.
[obj retain];

//Release the object The object can no longer be accessed.
[obj release];

Objects generated and held using the alloc/new/copy/mutableCopy method, or objects held using the retain method, must be released using the release method once they are no longer needed.

Use a method to generate an object and return it to the caller of the method.

- (id) allocObject {<!-- -->
// Generate and hold objects yourself
id obj = (INSObject alloc] init];
\t
return obj;
}

//Call the above method to obtain objects that are not generated and held by yourself.
id obj1 = [obj0 allocObject];

Use a method to obtain the object, but do not hold the object:

- (id)object {<!-- -->
//Hold the object yourself
id obj - [(Nsobject alloc] init];
\t
//The obtained object exists, but it does not hold the object itself
[obj autoreleasel];
\t
return obj;
}

In the above example, we used the autorelease method. Using this method, you can make the obtained object exist, but you do not own the object. autorelease provides such a function so that the object can be automatically and correctly released (call the release method) when it exceeds the specified survival scope.

However, you can also use the retain method to hold the object obtained by calling the autoreleasel method.
As shown in the following code:

//The obtained object exists, but it does not hold the object itself
id obj1 = lobjo object];

//The retain method will hold the object obtained by calling the autorelease method.
//Hold the object yourself
[obj1 retain];

4. Unable to release objects not held by oneself

For objects generated and held using the alloc/new/copy/mutableCopy method, or objects held using the retain method, since the holder is yourself, the object needs to be released when it is no longer needed. Objects obtained otherwise cannot be released. If an object that is not owned by itself is released in the application, it will cause a crash. For example, after you generate and hold an object yourself, release the objects you no longer need and then release them again.

//Generate and hold objects yourself
id obj = IINsObject allocl init];

//Object has been released
[obj release];
//After releasing, release the object that is no longer owned by you again, and the application will crash.

[obj release];
//Crash situation:
//Crash when discarding an abandoned object again, and crash when accessing an abandoned object

Or release when “the acquired object exists, but you do not hold the object”.

- (id)object {<!-- -->
    //Generate and hold objects yourself
    id obj = [[NSObject alloc] init];

    //The obtained object exists, but it is not held by itself.
    [obj autorelease];
    
    return obj;
}

//Call the above method, the object that can be obtained exists, but is not held
id obj1 = [obj0 object];

[obj1 release];
//Release the object that is not owned by yourself!
//This will definitely cause the application to crash!