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
Block定義成屬性為什么選擇copy修飾符?
MRC : Block的本質是函數指針,內存地址在棧區,使用Copy是為了把Block由棧區拷貝到堆區,共享給當前對象使用.
ARC : Block定義成屬性時,使用strong和copy的效果是一樣,但是蘋果官方建議使用copy.