Blocks:帶有自動變量(局部變量)的匿名函數.json
之因此可以匿名,是由於C語言函數本身爲其建立了名字-->規則是其所在的函數名和該block在其所屬函數中所處的順序值函數
//正常的block ^int (int count){return count + 1;}; //block能夠省略參數,例如省略返回值類型,則自動使用根據return的類型 ^(int count){return count + 1;}; //若不適用參數,則參數列表也能夠省略 ^void(void){}; //還能夠這樣寫 ^{};
在OC中,主要使用的是Block類型的變量spa
Block的能夠做爲參數傳進block裏,也能夠將Block類型變量做爲返回值返回,block之間能夠相互賦值,指針
//點擊事件Block typedef void(^ActionBlock)(); //帶參數的Block typedef void(^CallBackBlock)(id _Nullable obj); //帶參數的Block typedef void(^StatusBlock)(BOOL status); // 請求回調block typedef void(^ Success)(id _Nullable json); typedef void(^ Failure)(NSString * _Nonnull errorMSG);
直接放在.h裏使用方便code
Block截獲自動變量值對象
"帶有自動變量值"在block裏表現爲"截獲自動變量值"blog
也就是說:Block表達式截獲所使用的自動變量的值,即保存該自動變量的瞬間值.由於Block保存了自動變量的值,因此在執行block語法後,即便改寫Block中使用的自動變量的值,也不會影響block執行時自動變量的值.生命週期
//輸出應該是2
int value = 2; void (^block)(void) = ^{ NSLog(@"%i",value); }; value = 10; block();
Block之__block事件
若想在Block的表達式中將值賦給外部聲明的自動變量,須要在該自動變量上附加__block,io
//輸出值應該爲10 __block int value = 2; void (^block)(void) = ^{ value = 10; }; block(); NSLog(@"%i",value);
未添加__block的狀況下:截獲OC對象,調用變動對象的方法不會有問題,由於block內會截獲該對象的結構體實例指針.可是不能對該對象進行賦值操做.
Block的循環引用
緣由:在Block中使用強引用的對象,那麼Block從棧賦值到堆的時候,該對象爲Block持有,就容易引發循環引用
即對象持有block,block又持有對象.死循環
__weak 與 __block的區別
__block在ARC與MRC下均可以使用,能夠對對象及基本數據類型進行賦值,修改操做
__weak在ARC下可用,只能修飾對象,不能修飾基本數據類型
__block修飾的對象能夠在block中從新賦值,__weak修飾的則不能夠
Block修飾符
Block使用copy修飾,由於block默認是在棧區,棧區的特色是隨時均可能釋放,一旦釋放,則調用的就是空指針,copy操做會將其拷貝到堆區,這樣的話其生命週期就是隨當前對象的生命週期終止才終止,對象不銷燬就能夠調用