2019-04-11面试题

1. __block__weak的区别:

__block int num = 10; // __block能够修饰对象与基本数据类型
//    __weak int num = 10; // __weak只能修饰对象,不能修饰基本数据类型
self.block = ^{
    num++;
    NSLog(@"内部值:%d", num);
};
    
self.block();
NSLog(@"外部值:%d", num);

使用__block修饰基本数据类型:当没有使用__block修饰变量num时,此时的num变量在block内可读不可写,由于此时block内部会将变量作处理,从新生成一个变量指向num,使得在block内外操做的其实不是相同的num变量。当使用了__block修饰变量以后,block内部使用此变量时,不会再生成新的变量,因此此时外部对变量num的操做也会改变block内num变量的值。异步

使用__weak避免循环引用:使用block时,为了不循环引用,通常用__weak定义一个弱引用weakSelf,因为弱引用不持有对象实例,当对象不被使用时,weakSelf将会释放并被系统所回收,使得block再也不强引用着self不释放,避免出现循环引用。oop

总结性能

__block能够修饰对象和基本数据类型;在MRC和ARC下均可以使用,缺点在于在ARC下,会引发循环引用。
__weak只能修饰对象,不能修饰基本数据类型;不会发生循环引用。
__weak直接修饰生成对象会被释放,__block则不会code

2. block循环引用

在堆上的对象与堆上的对象互相引用形成的环,就会引发循环引用对象

对象被强引用(strong)后,就不会被释放,除非强引用者被释放。
循环引用就是,对象间相互强引用了对方,而致使双方都没法被释放。生命周期

循环引用带来的危害内存

  1. 内存泄漏、消耗变高
  2. APP性能变差,用户体验很差
  3. 闪退

**为了不循环引用,同时为了防止异步的block在回调的时,block执行的过程当中被意外释放,咱们使用__strong 对block外的__weak对象再次强引用,既可以防止引用循环,又可以保证代码的正确执行。**get

3. dealloc方法

对象被释放或者说一个对象或者类被置为nil的时候,执行dealloc方法it

正常状况下,每个OC对象最后应该都会调用dealloc方法,表示结束了生命周期,在内存中销毁。变量

什么状况下,会不调用dealloc方法?

  1. 控制器中使用了定时器后没有销毁,致使循环引用
  2. 协议delegate应该使用weak修饰,不然会引发循环引用
  3. 使用到block时,引发了循环引用

4. NSTimerRunLoop

NSTimer开启时,有时候会有延时(不会当即执行)。由于若是RunLoop正在执行一个持续性的运算,timer就会被延时触发。

UIScrollView上的定时器,在scrollView滑动的时候,定时器方法没有被调用,须要添加到RunLoopMode

NSTimer *timer=[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(Handlete) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
相关文章
相关标签/搜索