ARC 下内存泄露的那些点

ARC 下内存泄露的那些点

一、block 系列

ARC 下,当 block 获取到外部变量时,由于编译器无法预测获取到的变量何时会被突然释放,为了保证程序能够正确运行,让 block 持有获取到的变量,向系统显明:我要用它,你们千万别把它回收了!然而,也正因 block 持有了变量,容易导致变量和 block 的循环引用,造成内存泄露!

二、performSelector 系列

  • performSelector延时调用导致的内存泄露

performSelector 顾名思义即在运行时执行一个 selector,最简单的方法如下

- (id)performSelector:(SEL)selector;

这种调用 selector 的方法和直接调用 selector 基本等效,执行效果相同

[object methodName];
[object performSelector:@selector(methodName)];

三、addObserver 系列

addObserver 即 Objective-C 中的观察者,此系列常见于 NSNotification、KVO 注册通知。注册通知时,为了防止 observer 被突然释放,造成程序异常,需要持有 observer,这是造成内存泄露的一个隐患之一。

所以为什么需要在代码的 dealloc 方法中移除通知,原因就在于此。

NSNotificationcenter 需要 removeObserver 的原因是如果不移除的话,被观察者那么还会继续发送消息。如果此时观察者已经释放,消息会转发给其他对象,有可能造成严重的问题Effective Objective-C Notes:理解消息传递机制

四、NSTimer

在使用 NSTimer addtarget 时,为了防止 target 被释放而导致的程序异常,timer 会持有 target,所以这也是一处内存泄露的隐患。

// NSTimer 内存泄露
/**
 * self 持有 timer,timer 在初始化时持有 self,造成循环引用。
 * 解决的方法就是使用 invalidate 方法销掉 timer。
 */
// interface
@interface SomeViewController : UIViewController
@property (nonatomic, strong) NSTimer *timer;
@end
//implementation
@implementation SomeViewController
- (void)someMethod
{
    timer = [NSTimer scheduledTimerWithTimeInterval:0.1  
                                             target:self  
                                           selector:@selector(handleTimer:)  
                                           userInfo:nil  
                                            repeats:YES];  
}
@end

五、try...catch

Apple 提供了 错误处理(NSError)和 异常处理(NSException)两种机制,而 try...catch 就是使用 exception 捕获异常。NSError 应用在在绝大部分的场景下,并且这也是 Apple 所推荐。那什么时候用 NSException 呢?在极其严重的直接导致程序崩溃情况下才使用,并且无需考虑恢复问题。

欢迎大家多提供建议,便于完善!

你可能感兴趣的:(ARC 下内存泄露的那些点)