iOSeasy造成循引用的场景

场景一 :NStimer

timer就是一个能在从如今開始的未来的某一个时刻又或者周期性的运行我们指定的方法的对象

NSTimer运行的必要条件:相应线程的RunLoop要开启,mode要相应

以下看timer的循环引用:


如图,我们写这种一个类,当我们初始化这个类就会有一个timer开启。然后当我们去释放当前类的时候,是不会走dealloc函数的,由于timer会对当前类count +1,然后timer持有self,self持有timer就造成了死循环。造成内存泄露。而打破循环引用的方法就是Invalidate。


场景 二:[self performSelector:@selector(method:) withObject:self afterDelay:5];

当方法还没有运行的时候,要返回父视图释放当前视图的时候。self的计数没有降低到0,而导致无法调用dealloc方法,出现了内存泄露

 解决方式:

1.[NSObject cancelPreviousPerformRequestsWithTarget:self]

2.[NSObjectcancelPreviousPerformRequestsWithTarget:self selector:@selector(method1:)object:nil]


场景 三:addObserver

Q&A:

1.NSNotificationCenteraddObserver没有对这个对象进行引用计数1操作?

2.在一个已经释放的NSObject类 以及一个ViewController类发通知结果会如何?

3. [[NSNotificationCenter defaultCenterremoveObserver: name: object:nil]; 

.

  [[NSNotificationCenter defaultCenter]  removeObserver] 怎样选取


我们首先解决第2个问题。在一个已经释放的NSObject类 以及一个ViewController类发通知  NSObject会crash。会提示一个地址错误。说明通知仅仅是记住了他的地址指针,技术并没有加1,而对ViewController类发通知 不会发生crash。为什么会这样?

那就是:ViewController在dealloc的时候会调用  [[NSNotificationCenter defaultCenter]  removeObserver:self] ;

而我们怎么去验证呢。那就是给NSNotificationCenter加一个类别,重写removeObserver:self方法。就会非常easy的发现,你还会发如今dealloc的时候会移除系统的通知,实际上苹果就是这么做的。

最后一个问题:那么怎样让抉择? 就是在除了Dealloc以外的地方都不要调用removeObserver:self   而是使用单个移除的方法[[NSNotificationCenter defaultCenterremoveObserver: 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];

}


原文地址:https://www.cnblogs.com/gavanwanggw/p/7281084.html