IOS eight memory leak problem

Circular reference (Retain Cycle)

Firstly, what is the circular reference (retain cycle)
we assume we have two instances of A and B, B is a strong A property B, the reference count is 1, when A need to release, A will call the [B release] to release B, the reference count B the release is reduced to 0.

If this time will be a strong property B to A, then A and B strong reference to each other, the problem is coming. Because B A A is a strong reference, the reference count is never reduced to 0, when the strong original A reference object is released, A and B became an island reference each other, will never be released, it will cause a memory leak.

In the above example, is a very common reference cycle, adding the above code VC in dismiss or pop, and will not perform the dealloc method to prove that the memory leak. The cause of the leak is in the self as a property block, using the self pointer causes the self to be strongly referenced by the block, forming a reference cycle.

Summary of several common cases of memory leaks

1, Delegate/NSNotification

When we use the design pattern, we must pay attention to the delegate variables declared as weak type, like
such as the use of strong or other types of modification would lead to a circular reference, leading to dealloc () will not be called. NSNotification does not remove the notice will trigger some unexpected consequences.

2, Block

At present, most of the memory leaks in the project is due to the problem of block.
in ARC, when block gets to the external variable, the compiler cannot predict when access to variables are suddenly released, in order to ensure the correct procedure to run, let block get hold of variables to the system statement: I want to use it, you don’t get it recovered! However, it is also due to the block holds a variable, easily lead to variable and block cycle references, resulting in memory leaks

[_sortButton setButtonSpreadPreAction:^BOOL{if (_resultItems.count = = 0) {[progressHUD showText:@ "XXXX"]; return NO;} return YES;}];

The problem with this example is the use of block in the process of forming a circular reference: self holds sortButton; sortButton holds block; block holds self. The three forms a circular reference, memory leaks.

GCD has some system level API does not prompt circular references warning, but found by testing, most of the system also need to provide block __weak typeof WeakReference (self) weakSelf = self;
project in addition to the AFN third party component in the call to block are weak references.

3, NSTimer

NSTimer before the release, be sure to call [timer invalidate], not the result of the call is that NSTimer can not release its target, if target is just self, it will lead to the reference cycle.

- (void) performSelector: (SEL) aSelector withObject: (ID) anArgument afterDelay: (NSTimeInterval) delay

This is the official document:

This method sets up a timer to perform the aSelector message on the current thread s run loop. The timer “is configured to run in the default mode (NSDefaultRunLoopMode). When the timer fires, the thread attempts to dequeue the message from the run loop and perform the selector. It succeeds if the run loop is running and in the default mode; otherwise the timer waits until, the run loop is in the default mode.

Perhaps the system relies on a timer to ensure that the delay is triggered, but only when the runloop in default mode will execute successfully, otherwise selector will have been waiting for run loop switch to default. According to our previous statement on timer
, in fact, in fact, the call performSelector:afterDelay: will also cause a strong reference to the target system, that is, retain live. This way, if the selector has been unable to perform (if runloop is not running under default model), so that the child will also cause target has not been released, the occurrence of memory leaks. How to solve this problem? In fact, very simple, we at the appropriate time to cancel the call on the line, the system provides an interface:

(void) cancelPreviousPerformRequestsWithTarget: (ID) aTarget

Here I want to add a point, not only reference cycle of two objects, three four more are possible, even the number of rings is not only one, so to develop good habits in the invalidate code, the NSTimer method is called before stopping.

4, Image memory is too large

Picture memory leak case

5, Foundation and CoreFoundation reference will also cause memory leaks

6.AFN NSURLSession cannot be released

Solution: / /
/ / AFHTTPSessionManager modified manager method to replace the manager
; / / or inheritance, write a manager method / another way, two cases of single:

+ (AFHTTPSessionManager *) sharedHTTPSession{static dispatch_once_t onceToken; dispatch_once (& onceToken, [AFHTTPSessionManager ^{Manager = manager]; manager.requestSerializer.timeoutInterval = 30; [manager.requestSerializer setValue:@ "XMLHttpRequest" forHTTPHeaderField:@ "X-Requested-With"]; return manager;}}); + (AFURLSessionManager *) sharedURLSession{static dispatch_once_t onceToken2; dispatch_once & onceToken2 (urlsession = [[AFURLSessionManager, ^{alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; return urlsession;}});

7.UIWebView cannot release

Currently only use WKWebView. Other ways to try, no use

8 friends to share (no solution)