IOS development-reference counting and ARC, ios-counting arc

Source: Internet
Author: User

IOS development-reference counting and ARC, ios-counting arc
Here are the learning notes about memory management: reference count and ARC. Previously, automatic Reference count (ARC) was introduced in MacOS X 10.7 and iOS 5 to replace the previous Manual Reference count MRC (Manual Reference Counting) manage objects in Objective-C (also called MRR (Manual Retain Release )]. Today, almost all memory management matters are handed over to the compiler for iOS projects under ARC, and developers only need to focus on business logic. However, for iOS development, memory management is a very important concept. If you first need to write code with high memory usage efficiency and no bugs, you must master the details of its memory management model. I. Reference count 1. What is the relationship with memory management?

In Objective-C memory management, each object has its own counter: If you want to keep an object alive (for example, you want to reference this object ), it increases the reference count of the object. After it is used up, it decreases the count. When no one references the object and its count changes to 0, the system destroys it.

This isReference countThe role: used to indicate the number of objects that want to survive the program;

 

2. Introduction to reference count:

Reference Count, also called retain count, indicates the number of times an object is referenced. A simple and effective way to manage object lifecycles.

 

3. How reference counting works:

The process reference diagram is as follows:

(The image table is taken from the book 52 effective methods for writing high-quality iOS and OS X code)

 

4. Operation Reference counting method:

A. The following statements are stated in the NSObject protocol: 3Methods used to operate counters:
  • Retain: Reserved. Retention count + 1;
  • Release: Release. Retention count-1;
  • Autorelease: Later (when the "Auto release pool" is cleared), and then the count is decreased and retained, so the function is to delay the release of the object;
B. dealloc method: In addition, when the count is 0, the object will automatically call dealloc. What we can do in the dealloc method is to release the reference pointing to other objects and cancel subscribed KVO and notifications. (You cannot call the dealloc method by yourself, because the system will call the dealloc method at the right time during the runtime, and once the dealloc method is called, the object is no longer valid even if the subsequent method calls retain again .)

ThereforeReleaseThere will be two cases later:

Count> 1 before call, Count minus 1;

Count before call <1, the object memory is recycled;

C. retainCount: method for obtaining the reference count.

Eg: [object retainCount]; // get the reference count of the object

 

Retain, release, autorelease details:

RRole of etain:

After the call, the count is + 1, and the object operation is retained. However, when the object is destroyed and the memory is recycled, it is no longer valid even when the retain is used;

Autorelease:

Autorelease is registered to the autoreleasepool instead of being released immediately. When the pool ends, the pool is released and then the release is automatically called for release.

Autorelease looks like ARC, but in fact it is similar to the automatic variable (local variable) in C language. When an automatic variable is out of its scope (such as braces), the automatic variable will be automatically discarded, the release method of the object instance in autorelease is called. [unlike C, developers can set the scope of variables.]

Release time: An Autorelease pool is created in each Runloop. Every Autorelease, the system puts the Object into the current Autorelease pool and releases it at the end of the Runloop, when the pool is released, all objects in the pool are called Release. Therefore, in general, each object that accepts the autorelease message will be released before the next Runloop starts.

For example, the following scenarios are available:Change ARCUseManual managementYou can make the following settings: Under the Build Phases option of Targets, select the file to be compiled using ARC under Compile Sources, double-click it, and enter-Fno-objc-arcYou can use MRC to manually manage the memory;)

-(NSString *)getSting{    NSString *str = [[NSString alloc]initWithFormat:@"I am Str"];    return [str autorelease];}

The release operation in the automatic release pool is executed only when the next time cycle is executed. Therefore, the following is called:

NSString *str = [self getSting];NSLog(@"%@",str);

The returned str object is retained and delayed release. Therefore, you can output the returned str object without executing the retain operation before the NSLog statement.

Therefore, autorelease can prolong the object's life cycle. So that it can survive for a period of time after crossing the method call boundary.

Release:

Release immediately executes the release operation to reduce the count by 1;

When the reference count of an object is 1, call "[object release];". If you call the NSLog method to output the object, the program may crash. Of course, it is only possible, because after the "deallocated" exists in the object, it simply puts the "avaiable pool" back )", however, if the NSLog is executed and the Object Memory has not been overwritten, the object is still valid, so the program may not crash. Therefore, it is difficult to debug bugs caused by premature object release.

To avoid this situation, the pointer "object = nil" is usually cleared after the object is called, so that no pointer pointing to an invalid object will appear, that is, the pointer (dangling pointer );

Hanging pointer:Pointer to an invalid object.

 

So what is the retainCount value for sending a message to a released (dealloc) object?

The principle is that you cannot do this. Because the memory of this object has been recycled, and we send a retainCount message to a recycled object, the output result of this object should be uncertain, for example, to reduce the memory write operation, do not change the value from 1 to 0,Therefore, it is very likely to output 1. For example:

Person * person = [[Person alloc] init]; // at this time, Count = 1 [person retain]; // COUNT = 2 [person release]; // COUNT = 1 [person release]; // probably count = 1;

Although the Code in the fourth line changes the count 1 release once, the count of the person object will change to 0 in principle, but in fact, to optimize the object release behavior and improve the efficiency of the system, when retainCount is 1, the release system will directly recycle the object, instead of decreasing its count to 0. Therefore, the retainCount value of an object may never be 0;

Therefore, whether it is in the development environment of ARC or not, it is not recommended to use retainCount as the basis for whether an object exists in the memory.

 

 

 

Ii. ARC

1. Background:

ARC is a new feature launched by iOS 5, which is called Automation Reference Counting ).

Even if the Swift language was introduced at the WWDC conference in 2014, it still uses the ARC technology as its management method.

2. What is ARC?

It should be noted that ARC is not a GC (Garbage Collection Garbage Collector), it is just a Static Analyzer tool, and the principle behind it is dependent on the Static analysis capability of the compiler, by finding reasonable inserted reference counting Management Code during compilation, iOS developers can improve their development efficiency.

In Apple's documentation, ARC is defined as follows:

"Automatic reference counting (ARC) is a compiler-level function that simplifies the process of object lifecycle management (memory management) in Cocoa applications ."

3. What is ARC doing?

During the compilation phase, the compiler automatically inserts retain, release, and autorelease into the allocated objects in the project code, and the inserted code is invisible.

However, it should be noted that the reference counting rule still works in ARC mode, but the compiler will share most of the memory management work for developers, in addition to inserting the above Code, there is also a part of optimization and Analysis of memory management.

Purpose:

  • A.Reduces risks such as memory leakage;
  • B.Reduce code workload so that developers only need to focus on business logic;

4. What does ARC do for reference counting?

Automatically add code during compilation:

In the compilation phase, the compiler fills us with Memory Management Code such as retain, release, and autorelease that originally needs to be written at the appropriate time and place. Therefore, ARC is not a runtime feature, it is not like the garbage collection system during GC runtime in java. Therefore, we can also know that ARC is actually a feature of the compiler.

For example:

-(void)setup{    _person = [person new];}

In an environment with manual memory management, the value of _ person is not automatically retained, but the code compiled under ARC will become:

-(void)setup{    person *tmp = [person new];    _person = [tmp retain];    [tmp release];}

Of course, in the development work, retain and release can be omitted for developers. The ARC system will automatically complete the tasks to achieve the same effect.

But in fact, when the ARC system automatically calls these methods, it directly calls the method of the underlying C language instead of passing through the common Objective-C message dispatching control:

For example, in retain, ARC analyzes the location where a reserved operation needs to be called, and calls the underlying function objc_retain equivalent to retain, this is also why retain, release, or autorelease cannot be overwritten in ARC, because these methods are never directly called in ARC.

Optimization of components during runtime:

ARC is a feature of the compiler, but it also contains runtime components. The optimization is meaningful.

Example:

The person factory method personWithName can get a person object, which is called here and assigned to an instance of person _ one:

_one = [person personWithName:@"name"];

This may occur:

In the personWithName method, the autorelease method is called for an object before it is returned to _ one.

Because the instance variable is strongly referenced, the compiler needs to perform a reservation operation when setting its value.

Person * tmp = [person personWithName: @ "name"]; // The autorelease method has already been called for reservation before the personWithName method returns; _ one = [tmp retain];

Obviously,AutoreleaseFollowedRetainIs repeated. To improve performance, you can delete and discard the two.AutoreleaseThis concept also requires that the technology of returning objects is 1 more than the expected value. However, to backward compatibility with non-ARC conditions, ARC adopts another method:

ARC can beRuntimeThis redundant operation is detected.

  1. When an object is returned, it is not called directly.Autorelease, Instead of callingObjc_autoreleaseReturnValueTo detect the code to be executed after the returned results, includingRetainOperation, set a flag in the global data structure (the specific content of this data structure varies with the processor) without executingAutoreleaseOperation.
  2. Similarly, if the method returns an automatically released object, callPersonWithNameThe code segment of the method does not execute retain. Instead, it is executed.Objc_retainAutoreleaseReturnValueFunction. This function detects the flag bit. If it has already been set, it will not be executed.RetainOperation.

However, setting and detecting flag spaces is faster than calling autorelease and retain, which optimizes the processing of this situation.

The complete optimization results after modifying the two functions are as follows: [P126, an example of 52 effective methods for writing high-quality iOS and OS X code]

We can roughly describe the pseudo code of two functions as follows:

LikeObjc_autoreleaseReturnValueHow does this function detect whether the method caller will immediately retain the object? This should be handled by the processor.

The processor determines that the original machine code command must be viewed.

Therefore, only the compiler Author can know how to implement this function.

ARC security:

When writing the Property setting method (setter), if you use the manual management method, you may need to write the following code:

-(void)setObject:(id)object{    [_object release];    _object = [object retain];}

But this will cause a problem: if the value of the new object is the same as that of the Instance Variable _ object, and only the current instance variable object is still referencing this value, the release operation in the setting method will make the reserved count of this value 0 and the system will reclaim it. Therefore, the subsequent retention operation will cause the application to crash.

In the environment where ARC is used, it is impossible to send such a "boundary condition:

The code just now can be written in this way under ARC (of course, we know that if you do not need to override the setter method, you can also skip this method and directly use "self. object = xxx "can also be called safely .) :

-(void)setObject:(id)object{    _object = object;}

In addition, ARC will use a safe method to set: First retain the new value, then release the old value, and finally set the instance variable.

In the case of manual management, we need to pay special attention to this "edge situation", but under ARC, we can easily write this code, you don't have to consider how to deal with this situation.

Summary: Transfers memory managementCompilerAndRuntime ComponentsIn this way, the code can be optimized in a variety of ways, and the above is one of the methods.

 

5. ARC rules

The following code cannot be explicitly called:

(NSZone: Memory zone)

You can no longer use the NSAID utoreleasepool object. ARC provides the @ autoreleasepool block to replace it, which is more efficient;

About dealloc:

  • You cannot explicitly call dealloc;
  • You can no longer call [super dealloc] In dealloc (you need to call it in a non-ARC environment .);
  • Resources cannot be released in dealloc (different objects need to be released in non-ARC environments );

6. Ownership Modifier

In oc programming, to process objects, you can define variable types as id types or various object types. These delimiters can be used to accurately declare the lifecycle of object variables and attributes;

The object type is a pointer to an oc class such as NSObject, for example, "NSObject *". The id type is used to hide the class name section of the object type. It is equivalent to the commonly used "void *" in C *";

In ARC, the ownership modifier must be attached to the id and object types;

There are four types of ownership modifiers:

_ Strong:

Strong references: other objects can be referenced as strong references, which is equivalent to the retain feature. It indicates that the variables hold strong references to objects created by the alloc/new/copy/mutableCopy method group, A strongly referenced variable is retained in its scope and released after it exceeds the scope. It is the default modifier;

For example, the following code:

id objc = [[NSObject alloc] init];

In fact, the ownership modifier has been attached:

id __strong objc = [[NSObject alloc] init];

_ Weak:

When _ strong is used, two objects may be strongly referenced by each other, or one object may be strongly referenced by itself, and a circular reference (for example, a retained ring) may occur ), therefore, when an object exceeds its lifecycle, it is held by the system but is still being referenced by the system, causing memory leakage (the discarded object is beyond its lifecycle, );

When we modify the _ weak reference of objects that may send circular references, the weak reference variable will not hold the object, and the generated object will be released immediately to avoid circular reference, weak reference also has another feature. if the object is recycled by the system, the weak reference variable will automatically expire and be assigned a value of nil.

 _ Unsafe_unretained:Unsafe ownership master Xu, the memory management of ARC is the work of the compiler, and the variable with the _ unsafe_unretained modifier does not belong to the memory management object of the compiler. Like _ weak, circular references can also be avoided. However, the difference is that the variable in the __unsafe_unretained attribute is not set to nil, but is in the suspension state;

 

_ Autoreleasing:In ARC, "@ autoreleasepool block" is used to replace the generation of the class "nyoutoreleasepool". The autorelease method is called by assigning values to variables with the _ autoreleasing modifier;

 

Other: What do ARC need to pay attention?

1. Loop reference cannot be solved after block is used too much.

2. When encountering the underlying Core Foundation object, you needManual managementWhen calculating their reference counts, we need to convert keywords as bridge conversions to solve the problem of relative conversion between Core Foundation objects and Objective-C objects:

_ Bridge:You can use the _ bridge flag to convert an object from the Core Foundation framework data type to the Foundation framework data type without modifying the reference count of related objects (and vice versa ).

_ Bridge_retained:The reference count of related objects is added to 1,And canTo convert a Core Foundation framework data type object to a Foundation framework data type object, and take ownership of the object from the ARC.

_ Bridge_transfer:The Foundation framework data type object can be converted to a Core Foundation framework data type object, and the ownership of the object will be handed over to the ARC Management, that is, the reference count will be handed over to the ARC Management;

 

Conclusion: two classic books are recommended (it is estimated that many people have already finished reading them.

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.