對於block的理解,block的面試題


 

1、block跟swift中的閉包(closure)基本一樣,都常用於值的回調,特別是在多線程的網絡請求回調中,使用起來極為方便。

 

2、block的開頭是“^”,接着是由小括號所報起來的參數列,行為主體由大括號包起來。block有四種類型,分別是無參無返回、無參有返回、有參有返回、以及有參無返回,而一般使用的block都是有參block,因為使用block主要就是進行參數的傳遞。

 

3、使用block時要特別注意類的循環引用,例如在一個控制器中,self強指針指向一個對象,而這個對象又強指針指向一個block,而在block中,又強指針指向了self,從而造成循環引用,導致內存無法釋放,造成內存泄露。

 

4、解決循環應用的方法,常用__weak來打斷強引用,例如用__weak來定義一個weakself來指向self的地址,如果self被釋放,weakself指向的地址變為nil,從而打斷引用環。需要注意的是,__weak是ARC專有的,__unsafe__unretained可以用在ARC,也可以用於MRC,但__unsafe__unretained是“assign”形式,如果指向的對象被釋放,其指針地址保持不變,如果繼續使用該指針,就會出現“野指針”。

 

5、關於block內存管理,當block內部沒有引用外部變量時,block存放在全局區;在MRC下,當block內部引用外部變量時,block存放在棧區;當對該棧區的block進行copy操作時,block將存放在堆區。在ARC下,當block內部引用外部變量時,block存放在堆區;關於堆區與棧區的區別,棧區主要存放局部變量,定義的參數等,在函數結束,系統會自動回收其內存空間,而堆區一般用程序員自行分配釋放,若程序員不釋放,程序結束時,由系統回收。總的來說,使用棧區更為快捷,而使用堆區更為靈活。

 

6、如果要在block中修改外部變量,當變量是static全局變量時,block可以直接修飾,如果不是,可以用__block關鍵字來修飾,就可以在block內修改變量的值。

 

 

 7.關於block回調理解描述

  舉一個🌰例子:

 比如我很口渴,但我在忙,需要身邊的同事打水一起幫忙打,那么我需要把我的水杯給她,讓她去將接水(就相當於我們定義了准備了一個代碼塊,准備接收了外部要傳進來的數據),然后她接過水杯就進行去打水,(這個動作相當於:傳遞者需要准備一個屬性用來接收'接收者'准備好的代碼塊);將水打好交給我(當拿到數據,將數據傳遞給接收者,實現回調),那么我接到水杯就可以喝水了(就是相當於:拿到傳遞者的數據,進行我要實現的操作--"賦值");

 

 

 

為什么在block內部無法修改外部的變量,尤其是棧區?

 

因為block大多數用來做數據傳遞,需要傳遞到其他地方調用執行,局部的變量在傳遞數據的時候容易丟失.

 

 

解決block循環引用方法

 

ARC: 解決block 循環引用問題使用__weak修飾self

 

MRC : 解決block 循環引用問題—— 使用__block

 

使用typed聲明block
 
typedef void(^didFinishBlock) (NSObject *ob);
 
 這就聲明了一個didFinishBlock類型的block,
 然后便可用
 
 
@property (nonatomic,copy) didFinishBlock  finishBlock;
聲明一個block對象,注意對象屬性設置為copy,接到block 參數時,便會自動復制一份。
 
__block是一種特殊類型,
使用該關鍵字聲明的局部變量,可以被block所改變,並且其在原函數中的值會被改變。

 

 

 

 Block定義成屬性為什么選擇copy修飾符?

    MRC : Block的本質是函數指針,內存地址在棧區,使用Copy是為了把Block由棧區拷貝到堆區,共享給當前對象使用.

    ARC : Block定義成屬性時,使用strong和copy的效果是一樣,但是蘋果官方建議使用copy.

 

 

 

 使用block和使用delegate完成委托模式有什么優點?
首先要了解什么是委托模式,委托模式在iOS中大量應用,其在設計模式中是適配器模式中的對象適配器,Objective-C中使用id類型指向一切對象,使委托模式在iOS中的實現更為方便。了解委托模式的細節:
 
使用block實現委托模式,其優點是回調的block代碼塊定義在委托對象函數內部,使代碼更為緊湊;
適配對象不再需要實現具體某個protocol,代碼更為簡潔。
 
 
  多線程與block
 GCD與Block
 使用 dispatch_async 系列方法,可以以指定的方式執行block
 
 GCD編程實力
 
dispatch_async的完整定義
   void dispatch_async(
   dispatch_queue_t queue,
   dispatch_block_t block);
功能:在指定的隊列里提交一個異步執行的block,不阻塞當前線程
 
通過queue來控制block執行的線程。主線程執行前文定義的 finishBlock對象
dispatch_async(dispatch_get_main_queue(),^(void){finishBlock();}); 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM