场景一 :NStimer
timer就是一个能在从现在开始的未来的某一个时刻又或者周期性的执行我们指定的方法的对象
NSTimer执行的必要条件:对应线程的RunLoop要开启,mode要对应
下面看timer的循环引用:
-(void)setBlock:(TestBlock)block{
_block = [block copy];
}
- (id)init
{
if (self = [super init]) {
NSLog(@" do ing!!");
self.myTimer = [[NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(handleTimer:)
userInfo:nil
repeats:YES] autorelease];
}
return self;
}
- (void)handleTimer:(id)sender {
NSLog(@"%@ say: testTimer!", [self class]);
self.testCountView.layer.borderColor = [[UIColor whiteColor] CGColor];
}
- (void)clearTimer {
[_myTimer invalidate];
_myTimer = nil;
}
- (void)dealloc
{
// [self clearTimer];
NSLog(@"%s is dealloced",__FUNCTION__);
[super dealloc];
}
如图,我们写这样的一个类,当我们初始化这个类就会有一个timer开启,然后当我们去释放当前类的时候,是不会走dealloc函数的,因为timer会对当前类count +1,然后timer持有self,self持有timer就造成了死循环,造成内存泄露,而打破循环引用的方法就是Invalidate。
场景 二:[self performSelector:
当方法还没有执行的时候,要返回父视图释放当前视图的时候,self的计数没有减少到0,而导致无法调用dealloc方法,出现了内存泄露
解决方案:
1.[NSObject cancelPreviousPerformRequestsWithTarget:self]
2.[NSObjectcancelPreviousPerformRequestsWithTarget:self selector:@selector(method1:)object:nil]
场景 三:addObserver
Q&A:
1.向NSNotificationCenter中addObserver后,有没有对这个对象进行引用计数加1操作?
2.在一个已经释放的NSObject类 以及一个ViewController类发通知结果会怎样?
3. [[NSNotificationCenter defaultCenter] removeObserver: name: object:nil];
和.
[[NSNotificationCenter defaultCenter] removeObserver:] 如何选取
我们首先解决第2个问题,在一个已经释放的NSObject类 以及一个ViewController类发通知 NSObject会crash,会提示一个地址错误,说明通知只是记住了他的地址指针,技术并没有加1,而对ViewController类发通知 不会发生crash,为什么会这样?
那就是:ViewController在dealloc的时候会调用 [[NSNotificationCenter defaultCenter] removeObserver:self] ;
而我们怎么去验证呢,那就是给NSNotificationCenter加一个类别,重写removeObserver:self方法,就会很容易的发现,你还会发现在dealloc的时候会移除系统的通知,实际上苹果就是这么做的。
最后一个问题:那么如何让抉择? 就是在除了Dealloc以外的地方都不要调用removeObserver:self 而是使用单个移除的方法[[NSNotificationCenter defaultCenter] removeObserver: name: object:nil];
场景四:Try 有风险,Catch需谨慎
##
@try{
//可能抛出异常的代码
}
@catch(NSException *exception) {
//处理异常
}
@finally{
//finally 代码块是可选的
// 但如果写了 finallyblock,不管有没有异常,block 内的代码都会被执行
}
然后 我们就可以发挥了:
@try {
//可能抛出异常的代码
TestTryctch*object = [[TestTryctch alloc] init];
[object doSmMayThrowException];//异常函数
[object release];
}
@catch (NSException *exception) {
//处理异常
NSLog(@"throw an exception:%@", exception.reason);
}
@finally {
NSLog(@"finally execution");
}
上述代码会不会有异常???
会,当然会!, [object doSmMayThrowException];//异常函数 直接就会跳过 [object release]; ,产生内存泄露
场景五:死循环
CATransition*transition = [CATransition animation];
transition.duration= 0.5;
tansition.repeatCount= HUGE_VALL;
[self.view.layeraddAnimation:transition forKey:”myAnimation”]
,如果HUGE_VALL 为一个很大的数就会内存泄露 解决方案:
-(void)viewWillDisappear:(BOOL)animated{
[self.view.layer removeAllAnimations];
}