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];
相關文章
相關標籤/搜索