I know that with ARC there may be leaks in iOS. What are the most frequent types of leaks and how can they be avoided?
I know that with ARC there may be leaks in iOS. What are the most frequent types of leaks and how can they be avoided?
The main memory-related problem is retain
cycles. They occur when an object has a strong
pointer to a second object, and it has a strong
pointer to the first. Even when all references to these objects are removed, they still refer to each other and will not be deallocated. This can also occur indirectly through a chain of objects whose last one in the chain refers to the first.
To understand this kind of problem, it's important to know how memory management works in iOS. There is no garbage collector ; instead, the reference counting mechanism is used. Each pointer strong
adds 1 to the reference counter of the pointing object (in this case, the pointer retains the object). When the pointer no longer points to the object, the object reference counter is decremented by a unit (the object is said to release the pointer). The object is deallocated when its reference counter reaches zero.
That's why there are modifiers __unsafe_unretained
and __weak
. __unsafe_unretained
does not retain the object it points to (i.e., it does not increment the object reference counter), but if the object is deallocated, the pointer points to invalid memory. The __weak
does not retain the object and changes the pointer to nil
when the object is deallocated. These modifiers are used to point to delegates , as you generally do not want an object to retain its delegate, which could lead to a cycle.
CGImageRef
), which are allocated using malloc()
(or through a function that calls malloc()
). You are responsible for managing the memory of these objects in order to avoid memory leaks.
(Based on link )
ARC is a great help to solve memory leak problems, however, this does not mean that the programmer is free of responsibilities in this regard. While there is a strong reference pointing to an object it will be alive (spending memory).
This means that it may be interesting to remove all strong references from an object (object = nil), so that it dies at a certain time instead of letting it die at the end of the application.
It is also important to use weak type references whenever possible to avoid such problems.
If there is no such care the objects will be alive forever, even when totally useless for the program.
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 at the most basic levels) by running Clang Static Analyzer
through Xcode
itself. / p>
This tool should not be used as a definitive answer to problems, but it may give you an initial overview of the most critical points in your application.
XCode
> Product
> Analyze
(Preferably with target/scheme
set to device
).
Another common problem has to do with the blocks, for example if we have a property in a class that references a block and soon 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
};