IOS-ARC mechanism and iosarc Principle

Source: Internet
Author: User

IOS-ARC mechanism and iosarc Principle

Memory Management is an important topic in software development. If the memory is improperly managed, the memory is exposed, and the program in severe cases crashes.

The following describes the ARC (Automatic Reference Counting) Mechanism of iOS.

Historical Origins of ARC

During iOS1.0, Apple did not open the mobile development interface, and there was no iOS developer concept.

During iOS2.0, we managed the technical data MRC mechanism used by the memory.

During iOS5.0, Apple launched the ARC mechanism.

We know that when MRC manages the memory, we need to follow the golden rule "who creates, who releases, who references, and who manages". When we create an object, you need to consider when to release the memory. If you are not familiar with the memory management mechanism, it may cause memory leakage and excessive release.

Manual memory management can lead to many problems. During iOS5.0, Apple launched the automatic memory management ARC. At that time, the IDE was used XCode4.0. When we created the project, there is an option below, whether to use ARC, giving developers a proprietary choice, but the launch of ARC, there are few people to use ARC, XCode5.0, there is no such option, the ARC mechanism is selected by default when we create a project. To use MRC, We need to manually configure the project.

When the launch of the ARC, many people said that the GC mechanism of the iOS ARC and Android is very similar, but they are quite different. Among them, GCS is the runtime feature, while ARC is the compilation feature.

Use of ARC

The literal translation of ARC is the automatic reference count, which can be understood as automatic memory management. Does automatic memory management really not need to be managed? None. The ARC mechanism will also cause memory leakage. we need to pay attention to these problems when using them.

In MRC, we often use the keywords release, autorelease, and retain to retain the reference count or release objects. In ARC, we can't do that. If we use these keywords, our program cannot pass through the Basic compilation.

Since we do not need to manually release the created object, the system will release it for us when necessary. When will the object be released?

Before discussing this issue, let's first explain the basic principles for using ARC.

  • Objects with strong references will not be released.
  • An object is immediately released without a strong reference.
  • The objects pointed to by weak references are automatically empty when they are to be released.

Note: The created object is strongly referenced by default, such as: People = [People new]; equivalent _ strong People = [People new];

The following content covers all three principles.

I. Local objects

First, create a project and add a class People. The following is the content of the. m file of People.

 

1 @ implementation People 2-(id) init 3 {4 if (self = [super init]) 5 {6 NSLog (@ "% s" ,__ FUNCTION __); 7} 8 return self; 9} 10-(void) dealloc11 {12 NSLog (@ "% s" ,__ FUNCTION _); 13} 14 @ endPeople. m

 

In viewDidLoad, add People * p = [People new]; NSLog (@ "% s" ,__ FUNCTION __);

The output is as follows:

13:16:10. 589 textarc [2627: 93432]-[People init]
13:16:10. 600 textarc [2627: 93432]-[ViewController viewDidLoad]
13:16:10. 600 textarc [2627: 93432]-[People dealloc]

We found that the People object should not be released. From the print order, we can see that the People object is released after the viewDidLoad is executed.

Why are partial objects released after function execution?

In viewDidLoad, p is a strong reference, and the object will not be released, and the content in NSLog will be printed. However, after the function is executed, the strong reference pointer does not point to the object. According to the above rules, no strong pointer to the object will be immediately released, so after the viewDidLoad is executed, the object People will be released.

If we write in viewDidLoad as follows:

_ Weak People * p = [People new];
NSLog (@ "% s" ,__ FUNCTION __);

We can guess that the printed results will be different from the above.

13:22:10. 783 textarc [2682: 96983]-[People init]
13:22:10. 783 textarc [2682: 96983]-[People dealloc]
13:22:10. 784 textarc [2682: 96983]-[ViewController viewDidLoad]

Because the object does not have a strong pointer reference, the People will be released and the following print will be executed.

Ii. Global Variables

Now we define People as a global object and name it _ people.

Write the following code in viewDidLoad:

_ People = [People new];
NSLog (@ "% s" ,__ FUNCTION __);

The output is as follows:

13:28:32. 076 textarc [2764: 100790]-[People init]
13:28:32. 077 textarc [2764: 100790]-[ViewController viewDidLoad]

We found that the dealloc method of People is not called, because when the viewDid function is executed, there is a strong reference pointer pointing to People. According to the above rules, the object will not be released.

If we add _ weak: _ weak People * _ people before the global object;

Run the above Code and print the result as follows:

13:31:47. 816 textarc [2803: 102843]-[People init]
13:31:47. 827 textarc [2803: 102843]-[People dealloc]
13:31:47. 828 textarc [2803: 102843]-[ViewController viewDidLoad]

This result does not need to be explained. Although it is a global object, it is a weak reference. If there is no strong reference, the object will be released.

 

Iii. Global and local hybrid use

Now we define a global row strong pointer to People object p and create a local strong pointer object p1.

In viewDidLoad:

People * p1 = [People new];
P = p1;

The execution result is:

13:49:32. 380 textarc [3088: 111876]-[People init]
13:49:32. 383 textarc [3088: 111876]-[ViewController viewDidLoad]

Because p1 is a local strong reference, it is usually released after the function is executed. However, before the function is released, a global strong reference executes it, all People are not released.

If we write in viewDid as follows:

_ Weak People * p1 = [People new];
P = p1;

NSLog (@ "% s" ,__ FUNCTION __);

The output is as follows:

13:50:43. 647 textarc [3115: 112734]-[People init]
13:50:43. 651 textarc [3115: 112734]-[People dealloc]
13:50:43. 651 textarc [3115: 112734]-[ViewController viewDidLoad]

Because the local object is a weak reference, the object will be released. before being assigned to a global strong reference, it is empty and the object has been released.

4. Create object nesting

Suppose we have another class named Car. People has an attribute, @ property (nonatomic, strong) Car * car;

Now we declare a Global Object p.

In viewDidLoad:

P = [People new];
Car * c = [Car new];
P. car = c;
NSLog (@ "% s" ,__ FUNCTION __);

Print result:

13:57:21. 883 textarc [3220: 116572]-[People init]
13:57:21. 886 textarc [3220: 116572]-[Car init]
13:57:21. 886 textarc [3220: 116572]-[ViewController viewDidLoad]

Although the Car is a local reference, it is not released after the function is executed. Because p has a strong reference to it, all cars will not be released.

If we release People, the Car will also be released.

If we want to release a variable, we can directly assign a null value to the variable to release it.

For example:

P = [People new];
Car * c = [Car new];
P. car = c;
P = nil;
NSLog (@ "% s" ,__ FUNCTION __);

The output is as follows:

14:01:14. 703 textarc [3265: 118993]-[People init]
14:01:14. 706 textarc [3265: 118993]-[Car init]
14:01:14. 706 textarc [3265: 118993]-[People dealloc]
14:01:14. 706 textarc [3265: 118993]-[ViewController viewDidLoad]
14:01:14. 707 textarc [3265: 118993]-[Car dealloc]

V. Circular references

Add the property of Car in People and People in Car. (Pay attention to cross-reference issues)

In viewDidLoad:

People * p = [People new];
Car * c = [Car new];
P. car = c;
C. people = p;
NSLog (@ "% s" ,__ FUNCTION __);

Result:

14:05:50. 296 textarc [3320: 121202]-[People init]
14:05:50. 298 textarc [3320: 121202]-[Car init]
14:05:50. 298 textarc [3320: 121202]-[ViewController viewDidLoad]

We found that none of them were released, causing memory leakage. Of course we can release c or p with a value of nil. However, this writing is terrible. We need to determine what release decides to release.

How can this problem be solved?

When modifying attributes, do not use strong at the same time. You can use weak for one operation. The running result is as follows:

15:45:53. 289 textarc [3937: 150043]-[People init]
15:45:53. 298 textarc [3937: 150043]-[Car init]
15:45:53. 298 textarc [3937: 150043]-[ViewController viewDidLoad]
15:45:53. 298 textarc [3937: 150043]-[People dealloc]
15:45:53. 298 textarc [3937: 150043]-[Car dealloc]

 

ARC summary when using ARC, we can simplify our programming operations to a certain extent, but there will also be Memory leakage during use, we need to summarize the problems in actual use, so that our program has fewer bugs and potential bugs.

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.