IOS Memory Management

Source: Internet
Author: User

This essay is a summary of the "Understanding memory management" of the "ios Development Advanced" book, which is read by Tang Qi, and is shared here to everyone.

The memory management of the objective-c and Swift languages is based on the reference count "reference counting", and reference counting is a simple and effective way to manage the object life cycle. Reference counting is divided into manual reference count "arc:automatic Reference counting" and Auto reference count "mrc:manual Reference counting", now it's ARC, but we still need to know about MRC.

1. What is the principle of reference counting?

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

When a new pointer points to this object, his reference count is added 1;

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

When the object's reference count is 0 o'clock, it means that the object is no longer pointed to by any pointers, so we can destroy the object and reclaim the memory.

Because the reference count is simple and effective, Microsoft's com"component Object model", c++11 (reference counting-based smart pointer share_, in addition to the Objective-c language) PRT) also provides a memory management approach based on reference counting.

As an example:

New project, Xcode is the default open ARC, we here for the "appdelegate.m" file using MRC, the following configuration:

Select the target project, and then under "build phases" "compile sources" "appdelegate.m" file configuration compiler parameters "compiler flags" value "-fno-objc-arc"

1-(BOOL) Application: (UIApplication *) application didfinishlaunchingwithoptions: (Nsdictionary *) launchoptions {2NSObject *objo = [NSObjectNew];3NSLog (@"Reference Count:%lu", (unsignedLong) [Objo Retaincount]);//14NSObject *OBJB =[Objo retain];5NSLog (@"Reference Count:%lu", (unsignedLong) [Objo Retaincount]);//26 [Objo release];7NSLog (@"Reference Count:%lu", (unsignedLong) [Objo Retaincount]);//18 [Objo release];9NSLog (@"Reference Count:%lu", (unsignedLong) [Objo Retaincount]);//1Ten      One[Objo setvalue:nil Forkey:@"Test"];//Zombie object, sending message to wild pointer will error (EXC_BAD_ACCESS) A      -     returnYES; -}

Xcode does not monitor zombie objects by default, here we configure to open him, then we can see the specific tracking information:

You can also open the "instruments" toolset by selecting "profile" under "product". Then select "zombies", and then click the "choose" button in the lower right corner to enter the detection interface, click on the upper left corner of the "record" red dot button to start detection.

1.1 The above example, why was the last time obtained by retaincount a value of 1 instead of 0?

Because the object's memory has been reclaimed, we send a retaincount message to a reclaimed object, and his output is indeterminate, and if the object's memory is reused, it can cause the program to crash unexpectedly.

And when the last release, the system already knew to reclaim memory immediately, there is no need to reduce the retaincount minus 1, because no matter the minus 1, the object will be recycled, after the recovery of his memory area (including Retaincount value) is meaningless. Without Retaincount minus 1 to 0, you can reduce a memory operation and expedite the collection of objects.

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

Zombie object: Objects that occupy memory have been reclaimed, zombie objects can no longer be used.

Wild pointer: A pointer to a zombie object (memory not available) that sends an error message to the wild Pointer (exc_bad_access).

Null pointer: No pointer to any object (stored nil, NULL), sending a message to a null pointer does not give an error; A classic usage scenario for a null pointer is to get the server API data in development, the conversion field pointer is a null pointer, to avoid sending a message error.

2. Why do I need a reference count?

From the simple example above, we also do not see the real usefulness of reference counting, because the object's life cycle is only within one method. In a real-world scenario, we use a temporary object within a method, usually without having to modify his reference count, just to destroy the object before the method returns.

However, the really useful scenario for reference counting is in object-oriented programming architecture, where data is passed and shared between objects.

As an example:

If object a generates an object o, it needs to call a method of object B and pass the object o as a parameter.

In the absence of a reference count, the principle of general memory management is "who applies to whom to release", then object A needs to destroy the object O when object B no longer needs the object o. But object B may temporarily use the object o, you can think he is important, set him as a member of his own variable, in this case, when the destruction of the object o becomes a problem.

There are two ways of doing this:

(1) Object A immediately destroys the Parameter object o after invoking a method of object B, then object B needs to copy the object o, generating another object O2, and managing the life cycle of the object O2 itself. But there is a big problem with this approach, which is that he brings in more memory applications, duplication, and release of work. An object that could have been reused because it was inconvenient to manage his life cycle, simply destroying it, and re-structuring the same, was too much of an impact on performance.

(2) Object A is responsible for generating object o, and then object B is responsible for the destruction of Object O. If object B is just a temporary use of object o, it can be destroyed immediately after use, if object B takes a long time to use object o, do not destroy him. This approach seems to solve the problem of object replication, but he relies heavily on the mates of the A and B two objects, and the code maintainer needs to explicitly remember this programming convention. Moreover, because object O is generated and released in different objects, his memory management code is scattered among different objects, and management is also very laborious. If the situation is more complicated at this time, such as Object B needs to pass the Parameter object O to object C, then this object cannot be managed by object C in Object C. So the complexity of this approach is even higher and less desirable.

The advent of reference counting solves this problem well, in the process of passing the Parameter object O, which objects need to use him for a long time, he adds 1 to the reference count, minus 1 when used. All objects follow this rule, and the life cycle management of an object can be completely handed to the reference count. We can also easily enjoy the benefits of sharing objects.

2.1 What is the circular reference "reference cycles" problem, how to solve it?

Reference counting this kind of memory management method is simple, but one flaw is that he cannot automatically solve the problem of circular references.

As an example:

Object A and Object B reference each other as their own member variables, and only when they are destroyed, the reference count of their member variables is reduced by 1, because the destruction of object A and object B is interdependent, which results in what we call a circular reference problem.

Circular references can result in situations where no pointers have been able to access them, but the resources they occupy are still not released.

There are two main ways to solve circular reference problems:

(1) Clearly know where there is a circular reference, a reasonable time to actively disconnect a reference in the ring, so that the object can be recycled. This method is not commonly used because he relies on the developer to manually explicitly control it, which is equivalent to returning to the memory management age of "who applied for release".

(2) using weakly referenced "weak reference","weak""__weak" type, this method is commonly used. A weak reference does not increase his reference count, although it holds the object. A classic usage scenario for weak references is the "delegate" protocol pattern of the principal agent.

Are there any tools in 2.2 Xcode that can detect circular references?

There is a "instruments" toolset in Xcode that makes it easy to detect circular references.

As an 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.

Then select "leaks", and then click the "choose" button in the lower right corner to enter the detection interface, click on the upper left corner of the "record" red dot button to start detection.

3. Memory management for Core Foundation objects

ARC is a compiler feature that is not a runtime feature, nor a garbage collector "gc".

ARC is able to solve 90% of the memory management problems in IOS development, but another 10% of the memory management issues need to be handled by the developer themselves, primarily as part of interacting with the underlying core foundation objects, as the underlying core foundation objects are not managed by ARC. So you need to maintain the reference count for these objects yourself.

In fact, the Cfretain and Cfrelease methods used by Core Foundation objects can be considered equivalent to the retain and release methods of Objective-c objects, so we can do similar management in MRC.

3.1 in ARC, in what way can the Core Foundation object be converted to a Objective-c object?

The process of conversion is actually telling the compiler how to adjust the reference count of the object.

Here we can use bridging "bridge" related keywords to do the conversion work, the following is the description of these (double underscore) keywords:

(1) __bridge: Do only type conversion, do not modify the reference count of related objects, the original Core Foundation object when not used, you need to call the Cfrelease method.

(2) __bridge_retained: After the type conversion, the reference count of the related object is added 1, and the original Core Foundation object needs to call the Cfrelease method when it is not used.

(3) __bridge_transfer: After the type conversion, the reference count of the related object is given to ARC management, and the original Core Foundation object does not need to call the Cfrelease method when it is not used.

We can solve the problem of relative conversion between Core Foundation objects and Objective-c objects by using the above three conversion keywords rationally according to the specific business logic.

IOS Memory Management

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.