iOS可能导致内存泄漏的情况

iOS可能导致内存泄漏的情况_第1张图片

1.循环引用

常见于两个VC相互引用,通过@class解决;

block 循环引用,通过__weak解决。

Use Weak References to Avoid Retain Cycles

2.发生异常时

使用@try{}@catch{},当异常发生时,无法释放对象。

在ARC下,无法在@finally{}里边调用release方法,只能通过添加编译标识:-fobjc-arc-exceptions,添加之后会产生大量额外代码,一般情况不要开启改标识。如果你必须要开启改标识来保证不出现异常崩溃,那你应该重新审视你自己的代码,你的代码肯定是有问题的。一般只有在这种情况下使用异常捕获:如果不捕获异常应用就会终止。如果出现这种情况,应用都终止了,还担心啥内存泄漏。而且,这中情况将要发生时,也没有一个合适的时机来添加代码来使得异常变得安全。

3.CoreFoundation对象没有调用CFRelease释放

CoreFoundation里边是纯 C 的API,需要自己释放。

4.heap(堆)上分配的内存没有调用free释放

堆上分配的内存需要自己手动释放。

5.大次数循环时创建了很多临时变量没有释放

Use Autorelease Pool Blocks to Reduce High-Memory Waterline

在循环内部添加@autoreleasepool{/*...*/}。

6.数据库、connection、socket 用完没有关闭,文件描述符(file descriptors)用完没有释放。

7.调试模式下开启僵尸调试

NSZombieEnabled=“YES” (Enable Zombie Objects),开启之后对象占用的内存不会被释放。

8.定时器使用完没有调用 invalidate 方法

如果NSTimer的target指向self,而该定时器赋给了该类的一个实例变量,那么timer将引用当前类,当前类的实例变量又引用了timer,就造成了循环引用。您可以授权其他对象来调用invalidate方法,但是什么时机调用您是不知道的。所以该循环引用其实无法很好地解决,不过您可以考虑给NSTimer添加一个类别,添加一个用block实现的定制方法。

@interface NSTimer (LLBlocksSupport)

+ (NSTimer *)ll_scheduledTimerWithInterval:(NSTimeInterval)interval

                                                             block:(void(^)())block

                                                         repeats:repeats;

@end

@implentation NSTimer (LLBlocksSupport)

+ (NSTimer *)ll_scheduledTimerWithInterval:(NSTimeInterval)interval

                                                                  block:(void(^)())block

                                                              repeats:repeats

{

        return [self scheduledTimerWithInterval:interval

                                                             target:self

                                                          selector:@selector(ll_blockInvoke:)

                                                         userInfo:[block copy]

                                                          repeats:repeats];

}

+ (void)ll_blockInvoke:(NSTimer*)timer {

        void (^block)() = timer.userInfo;

        if (block) {

                block();

        }

}

@end

这样,target是NSTimer自己,就不会导致循环引用了。

9.播放器使用完没有调用 stop 方法

可用Xcode的Instruments里边的Leaks检测内存泄漏。要用代码检测泄漏,请 到这里。

你可能感兴趣的:(iOS可能导致内存泄漏的情况)