What types of retain Cycles can be generated with ARC?

Asked

Viewed 379 times

7

I know that with ARC there can be Leaks in iOS. What are the most frequent Leaks types and how they can be avoided?

4 answers

8

The main problem related to memory is the cycles of retain. They occur when an object has a pointer strong for a second object, and this has a pointer strong to the former. Even when all references to these objects are removed, they still refer to each other and will not be displaced. This can also occur indirectly, through a string of objects whose last in the string refers to the first.

To understand this kind of problem, it’s important to know how memory management works on iOS. There’s no Garbage Collector; instead, the reference counting mechanism is used. Each pointer strong adds 1 to the reference counter of the pointed object (in this case the pointer is said to retains the object). When the pointer stops pointing to the object, the object’s reference counter is decremented into a unit (it is said that the pointer loose the object). The object is displaced when its reference counter reaches zero.

That’s why there are modifiers __unsafe_unretained and __weak. The __unsafe_unretained does not retain the object it points to (i.e., does not increment the object’s reference counter), but if the object is offset, the pointer will point to invalid memory. The __weak does not retain the object and changes the pointer to nil when the object is displaced. These modifiers are used to point to delegates, for in general you do not want an object to retain its delegate, which could lead to a cycle.

Another important point is that ARC does not manage the memory of C types, such as those of the Core Foundation framework (e.g..: CGImageRef), that are allocated using malloc() (or through a calling function malloc()). You are responsible for managing the memory of these objects in order to prevent memory leaks.

(Based on https://stackoverflow.com/questions/6260256/what-kind-of-leaks-does-automatic-reference-counting-in-objective-c-not-prevent)

2

ARC is a great help in solving memory leak problems, but that doesn’t mean the programmer is free of responsibility for that. While there is a Strong reference pointing to an object it will be alive (wasting memory).

This means that it may be interesting to remove all the strong references of an object (Object = nil), so that it dies at a certain instant rather than letting it die at the end of the application.

It is also important to use Weak references whenever possible to avoid this type of problem.

If there is no such care the objects will stay alive forever, even when totally useless for the program.

1

Ignoring for a moment the theoretical part, which has already been well discussed by the other answers, you can have a more practical view of these problems (at least on more basic levels) running the Clang Static Analyzer through own Xcode.

This tool should not be used as a definitive answer to problems, but may present an initial view of the most critical points of your application.

XCode > Product > Analyze (Preferably with the target/scheme setado to device).

0

Another common problem has to do with blocks, for example if we have a property in a class that references a block and then inside the block we use self we can create a circular reference.

@property (nonatomic, copy) MyBlock block;

self.block = ^{
                NSLog(@"object is %@", self); // retain cycle
            };

__weak me = self; 
self.block = ^{
                    NSLog(@"object is %@", me); // no retain cycle
                };

Browser other questions tagged

You are not signed in. Login or sign up in order to post.