IOS memory management and ios Memory Management

Source: Internet
Author: User

IOS memory management and ios Memory Management

This article will record the summary of the "understanding memory management" knowledge point in the "iOS development advanced" book written by Tang Qiao. I will share it with you here.

 

Objective-C and Swift language memory management methods are based on Reference count "Reference Counting", and Reference count is a simple and effective way to manage object lifecycles. The Reference count is divided into Automatic Reference count "ARC: Automatic Reference Counting" and Manual Reference count "MRC: Manual Reference Counting". Currently, ARC is used, but we still need to know MRC.

 

1. What is the principle of reference counting?

When we create a new object, its reference count is 1;

When a new Pointer Points to this object, the reference count is increased by 1;

When a pointer associated with an object no longer points to him, his reference count is reduced by 1;

When the reference count of an object is 0, it means that the object is no longer pointed by any pointer. In this case, we can destroy the object and recycle the memory.

 

Since reference counting is simple and effective, in addition to the Objective-C language, Microsoft's COM "Component Object Model" and C ++ 11 (Intelligent pointer share_prt based on reference counting) and other languages also provide memory management based on reference count.

For example:

Create a project. By default, Xcode enables ARC. Here we use MRC for the "AppDelegate. m" file, and perform the following Configuration:

Select the target project and configure the Compiler parameter "Compiler Flags" to "-fno-objc-arc" in the "AppDelegate. m" file of "Build Phases" under "Compile Sources 」

1-(BOOL) application :( UIApplication *) application didfinishlaunchingwitexceptions :( NSDictionary *) launchOptions {2 NSObject * objO = [NSObject new]; 3 NSLog (@ "Reference Count: % lu ", (unsigned long) [objO retainCount]); // 1 4 NSObject * objB = [objO retain]; 5 NSLog (@ "Reference Count: % lu", (unsigned long) [objO retainCount]); // 2 6 [objO release]; 7 NSLog (@ "Reference Count: % lu", (unsigned long) [objO retainCount]); // 1 8 [objO release]; 9 NSLog (@ "Reference Count: % lu", (unsigned long) [objO retainCount]); // 110 11 [objO setValue: nil forKey: @ "test"]; // zombie object. An error (EXC_BAD_ACCESS) 12 13 return YES; 14} is returned when a message is sent to the wild pointer}

By default, Xcode does not monitor zombie objects. Here we configure to enable it, and then we can see the specific tracking information:

 

You can also select "Profile" under "Product" to open the "Instruments" toolset. Select "Zombies" and click "Choose" in the lower right corner To Go To The detection page. Then, click the "Record" red dot button in the upper left corner to start detection.

 

1.1 In the above example, why is the last value obtained through retainCount 1 instead of 0?

Because the memory of this object has been recycled, we send a retainCount message to a recycled object. The output result is uncertain. If the memory occupied by this object is reused, the program may crash abnormally.

In addition, when the last release is executed, the system knows that the memory is to be recycled immediately, so there is no need to reduce retainCount by 1, because no matter whether it is reduced by 1, the object will be recycled, it makes no sense to recycle the memory area (including the retainCount value. If you do not reduce retainCount by 1 to 0, you can reduce one memory operation to Accelerate object recycling.

 

1.2 What are zombie objects, wild pointers, and null pointers?

Zombie object: the occupied memory has been recycled, and the zombie object cannot be used any more.

Wild pointer: pointer to a zombie object (memory unavailable). An error is returned when a message is sent to the wild pointer (EXC_BAD_ACCESS ).

NULL Pointer: no pointer to any object (nil and NULL are stored). No error is returned when messages are sent to NULL pointers; A typical use case of NULL pointer is to convert the wild pointer to a null pointer when obtaining Server API data during development to avoid message sending errors.

 

2. Why is reference count required?

From the simple example above, we still cannot see the true usefulness of reference counting, because the lifecycle of this object is only within a method. In actual application scenarios, we use a temporary object in the method. Generally, we do not need to modify its reference count. We only need to destroy the object before returning the method.

However, the scenario where reference counts are used is to transfer and share data between objects in an object-oriented programming architecture.

 

For example:

If object A generates an object O, you need to call A method of object B and pass the object O as A parameter.

In the absence of reference counting, the general principle of memory management is "who applies for release". Therefore, object A needs to stop object O when object B no longer needs it, destroys the object O. However, object B may temporarily use object O, or it may be important to set it as a member variable. In this case, when to destroy the object O becomes a problem.

There are two ways to do this:

(1) After calling A method of object B, object A immediately destroys the parameter object O, and object B needs to copy the object O to generate another object O2, at the same time, you can manage the lifecycle of the object O2. But there is a big problem with this approach, that is, it brings more memory application, replication, and release work. An object that can be reused. Because it is inconvenient to manage its lifecycle, the object is simply destroyed and re-constructed in the same way, which affects performance.

(2) object A is only responsible for generating object O, and then object B is responsible for destroying object O. If object B only uses Object O temporarily, it can be destroyed immediately after it is used up. If object B needs to use object O for a long time, it will not be destroyed. This seems to solve the problem of object replication, but it is strongly dependent on the combination of objects A and B. The Code maintainer needs to clearly remember this programming convention. In addition, because the generation and release of the object O are in different objects, the memory management code of the object O is scattered among different objects, which is also difficult to manage. If the situation is more complex at this time, for example, if object B needs to pass the parameter object O to object C, this object cannot be managed by Object C in Object C. Therefore, this method is more complex and not desirable.

The occurrence of reference count solves this problem well. During the transfer process of parameter object O, when an object needs to be used for a long time, it adds the reference count to 1, 1 after use. All objects follow this rule, and the object lifecycle management can be handed over to reference count. We can also easily enjoy the benefits of shared objects.

 

2.1 What is the Reference Cycles loop Reference? How can this problem be solved?

The memory management method of reference counting is simple, but there is a flaw that it cannot automatically solve the problem of circular reference.

For example:

Objects A and B reference each other as their member variables. The reference count of their member variables is reduced by 1 only when they are destroyed, because the destruction of object A and object B is mutually dependent, we are talking about the circular reference problem.

Circular references may cause the resources they occupy to be released even if no pointers are available to them.

There are two main methods to solve the circular reference problem:

(1) clearly knows where circular references exist, and proactively disconnects a reference in the ring at a reasonable time, so that the object can be recycled. This method is not commonly used, because it relies on the developer to manually control it explicitly, which is equivalent to returning to the memory management age of "who applied for release.

(2) Use Weak references of the "weak Reference" and "weak" and "_ Weak" type. This method is commonly used. Weak references hold objects, but do not increase the reference count. A typical use case of weak references is the delegated proxy "delegate" protocol mode.

 

2.2 is there any tool in Xcode that can detect circular references?

The "Instruments" toolset in Xcode allows you to easily detect cyclic references.

For example:

1 - (void)viewDidLoad {2     [super viewDidLoad];3     4     NSMutableArray *mArrFirst = [NSMutableArray array];5     NSMutableArray *mArrSecond = [NSMutableArray array];6     [mArrFirst addObject:mArrSecond];7     [mArrSecond addObject:mArrFirst];8 }

You can select Profile under Product to open the Instruments toolset.

Select "Leaks" and click "Choose" in the lower-right corner To Go To The detection page. Then, click "Record" in the upper-left corner to start detection.

 

 

 

 

3. Core Foundation Object Memory Management

ARC is a compiler feature. It is not a runtime feature, not a garbage collector "GC 」.

ARC can solve 90% of memory management problems in iOS development, but the other 10% of memory management problems need to be handled by developers themselves, which is mainly the part of interaction with the underlying Core Foundation object, because the underlying Core Foundation objects are not managed by ARC, you need to maintain the reference count of these objects by yourself.

In fact, the CFRetain and CFRelease methods used by Core Foundation objects can be considered to be equivalent to the retain and release methods of Objective-C objects, so we can perform similar management in MRC mode.

 

3.1 In ARC, how can we convert a Core Foundation object to an Objective-C object?

The conversion process tells the compiler how to adjust the reference count of an object.

Here we can use the bridge-related keywords for conversion. The following are descriptions of these (double-underline) KEYWORDS:

(1) _ bridge: only performs type conversion without modifying the reference count of related objects. The CFRelease method must be called when the original Core Foundation object is not used.

(2) _ bridge_retained: After type conversion, add the reference count of the related object to 1. When the original Core Foundation object is not used, call the CFRelease method.

(3) _ bridge_transfer: after the type conversion, the reference count of the related object is handed over to the ARC Management. The CFRelease method is not required when the original Core Foundation object is not used.

Based on the specific business logic, we can use the above three conversion keywords to solve the problem of relative conversion between Core Foundation objects and Objective-C objects.

 

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.