Objective-C 内存管理浅析与循环强引用举例
理解
- 变量
- 作用域
- 变量废弃
- 持有对象
- 释放对象
- 对象所有者(引用计数)
- 对象废弃
- 变量所有权修饰符对对象的影响
对象相互持有导致循环强引用,举例如反复执行任务的NSTimer对象的目标对象
又保留了计时器对象,若该NSTimer对象被目标对象持有,便必定会发生循环强引用,因为NSTimer对象会持有目标,
而该NSTimer对象又是目标对象的成员变量也就是目标对象又持有该NSTimer对象
此循环强引用会一直持续到目标对象调用NSTimer对象的invalidate方法释放该NSTimer对象
可通过扩展NSTimer类利用block与__weak所有权修饰符解决该循环强引用
#import<Foundation/Foundation.h> @interface NSTimer(BlocksSupport) +(NSTimer *)scheduledTimerWithTimeInterval: (NSTimeInterval)interval block:(void(^)())block repeats:(BOOL)repeats; @end @implementation NSTimer(BlockSupport) +(NSTimer *)scheduledTimerWithTimeInterval: (NSTimeInterval)interval block:(void(^)())block repeats:(BOOL)repeats { return [self scheduledTimerWithTimeInterval:interval target:self selector:@selector(blockInvoke:) userInfo:[block copy] repeats:repeats]; } +(void)blockInvoke:(NSTimer *)timer{ void(^block)()=timer.userInfo; if(block){ block(); } }
//在别的Class类使用的时候 -(void)startAction{ __weak Class *weakSelf=self;//定义一个指向自己的弱引用 _myTimer=[NSTimer scheduledTimerWithInterval:5.0 block:^{ Class *strongSelf=weakSelf;/*块捕获该指向自己的弱引用,不直接捕获普通的self变量,因此block不持有该Class对象 然后马上让__strong变量持有该__weak的Class对象保证实例在执行期间持续存活, 也就是说strongSelf也是持有了Class对象的,但是,但是,但是,strongSelf是在block体 中声明的变量,其生命周期仅存block块,在block块执行完后便释放,也就不持有Class对象了*/ [strongSelf excueAction]; } repeats:YES]; } -dealloc{ [_myTimer invalidate];/*当外界持有Class对象的最后一个引用将其释放的时候,该方法会被执行,从而还会让计时器停止工作。 若开发者忘记在dealloc中调用invalidate方法停止计时器,那么计时器执行的block块中的weakSelf会变成nil strongSelf也就指向了nil,从而计时器执行空操作。*/ }