Objective-C 内存管理浅析与循环强引用举例

理解

  1. 变量
  2. 作用域
  3. 变量废弃
  4. 持有对象
  5. 释放对象
  6. 对象所有者(引用计数)
  7. 对象废弃
  8. 变量所有权修饰符对对象的影响

对象相互持有导致循环强引用,举例如反复执行任务的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,从而计时器执行空操作。*/
}

 

posted @ 2016-03-13 11:49  Jk_Chan  阅读(307)  评论(0编辑  收藏  举报