Block總結(jié)

BLOCK

block的描述: 他是類似函數(shù)指針的一個(gè)代碼塊的內(nèi)聯(lián)封裝, 他可以將一個(gè)函數(shù)體作為對(duì)象傳遞

block的本質(zhì): 對(duì)象

block的效率: 高于函數(shù)調(diào)用


聲明一個(gè)block

? ? ? ? ? ?返回值 (^名稱)(以”逗號(hào)”分割的參數(shù)), 參數(shù)部分可以不寫參數(shù)名只寫類型

范例:

? ? ? ? ? ? ? void ?(^myFirstBlock)( int a, NSString *s, UIButton *button )

? ? ? ? ? ? BOOL (^mySecondBlock)(void)

? ? NSString * (^myThirdBlock)(CGFloat, float)


定義一個(gè)block

? ? ? ? ?^可省略的返回值(以”逗號(hào)”分割的參數(shù)){代碼塊}

范例:

? ? ? ? ^void(int a){NSLog(@"一個(gè)int參數(shù), 無返回值的block"); }?

? ? ? ? ^{ NSLog(@"一個(gè)無參數(shù),無返回值的block"); }? ? ? ? ? ? ? ??

? ? ? ? ^int(int a, int b){ NSLog( @"一個(gè)兩個(gè)int參數(shù), 返回兩個(gè)數(shù)相加的block, 結(jié)果%d", a + b ); return a + b; }


block作為函數(shù)參數(shù)

? ? ?? ? block作為參數(shù), 參數(shù)名后綴, 類型格式為: ( 返回值(^)(參數(shù)) )block名?

范例:

- (void)test:(int(^)(int))paramBlock

{

? ? ? ? NSLog( @"打印block返回結(jié)果:%d", paramBlock(10));

}


?block作為參數(shù)的函數(shù)調(diào)用:

? ? ? ? ?將block定義部分或?qū)lock對(duì)象傳入函數(shù)調(diào)用的參數(shù)部分

范例:

[self test:^(int a){

? ? ? ? return a * a;

}];


__block:

block只能只讀的訪問局部變量, 若需要修改局部變量, 需要通過__block修飾該變量, 該修飾符會(huì)使block自動(dòng)復(fù)制該對(duì)象的指針,即指針拷貝, 當(dāng)對(duì)該對(duì)象執(zhí)行寫操作時(shí), 其實(shí)就是操作其指針指向的對(duì)象進(jìn)行操作.

若不加該修飾符, block僅自動(dòng)復(fù)制需要訪問的局部變量的值副本(值拷貝), 因此只能進(jìn)行只讀操作.

__weak:

使用block特別要注意的一點(diǎn)就是防止循環(huán)引用的發(fā)生, block作為一個(gè)對(duì)象被持有者持有,若block內(nèi)部也持有該持有者將會(huì)導(dǎo)致循環(huán)引用,導(dǎo)致相互持有, 永遠(yuǎn)無法銷毀彼此的內(nèi)存問題, 若不能規(guī)避該問題, 則需要通過使用__weak修飾 block要訪問的持有者變量, 防止循環(huán)引用的發(fā)生. 尤其是block所在的self.

__strong

該修飾符在block內(nèi)的主要作用是防止__weak修飾的指針在block運(yùn)行期間被外部銷毀, 導(dǎo)致block無法順利完成原定功能. 所以當(dāng)訪問的外部變量用__weak修飾時(shí), block內(nèi)部最好再有一個(gè)__strong修飾的同類型指針指向__weak指針, 這樣就可以確保, 在block內(nèi)部的這個(gè)指針可以運(yùn)行完成. 隨著block運(yùn)行完成, __strong修飾的指針也將自動(dòng)銷毀, 進(jìn)而__weak指針也會(huì)自動(dòng)置nil.


block外部變量訪問

block可以訪問和修改全局變量

block只能只讀的訪問局部變量(值傳遞, block內(nèi)部復(fù)制了一個(gè)副本), 若加了__block修飾, 就改為引用傳遞,可修改局部變量


block底層淺談

block本身包含一個(gè)結(jié)構(gòu)體

struct __block_impl

{

void *isa;

int Flags;

int Reserved;

void *FuncPtr;

}

block分為三種類型, __block_impl的isa指針負(fù)責(zé)標(biāo)記block類型

_NSConcreteGlobalBlock: 全局靜態(tài)block, 當(dāng)block內(nèi)不訪問任何外部變量, 或者訪問的是全局作用域,成員變量的, 屬于該類型, 內(nèi)存管理方式和函數(shù)一致

_NSConcreteStackBlock 棧block, 由系統(tǒng)管理內(nèi)存, 函數(shù)返回時(shí)銷毀, 訪問的外部變量由block從棧上copy到堆上, 保證了作用域結(jié)束后, block仍然可以訪問

_NSConcreteMallocBlock 堆block, 由開發(fā)者控制, 引用計(jì)數(shù)為0時(shí)銷毀


block幾種自身copy的情況, 若觸發(fā)一下情況, block將自動(dòng)拷貝自身到堆中, 確保自身作用域內(nèi)的變量的生命周期更長(zhǎng)久

1.顯式執(zhí)行copy, [block copy];

2.block作為返回值的時(shí)候

3.block被賦值給__strong類型的對(duì)象或者block的內(nèi)部變量時(shí)

4.block作為參數(shù)傳入帶有usingBlock的CocoaFramework方法

5. block作為參數(shù)傳入GCD的API時(shí)


其他:

__typeof, __typeof__, typeof 這三個(gè)關(guān)鍵字實(shí)現(xiàn)了一個(gè)相同的功能, 獲取參數(shù)的類型名稱并返回

UIViewController *vc;

__typeof(vc) vc2;

這樣就可以在不知道vc指針類型的情況下, 再聲明一個(gè)同類型的vc2

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 2.1 Blcoks概要 2.1.1 什么是Blocks Blocks是C語言的擴(kuò)充功能——“帶有自動(dòng)變量(即局部...
    SkyMing一C閱讀 2,448評(píng)論 6 18
  • 《Objective-C高級(jí)編程》這本書就講了三個(gè)東西:自動(dòng)引用計(jì)數(shù)、block、GCD,偏向于從原理上對(duì)這些內(nèi)容...
    WeiHing閱讀 10,089評(píng)論 10 69
  • 參考 Block編譯代碼解讀:block沒那么難(一、二、三)iOS進(jìn)階——iOS(Objective-C) 內(nèi)存...
    啊哈呵閱讀 884評(píng)論 0 3
  • Blocks Blocks Blocks 是帶有局部變量的匿名函數(shù) 截取自動(dòng)變量值 int main(){ ...
    南京小伙閱讀 1,069評(píng)論 1 3
  • — —是否曾有一本書,是否曾有一個(gè)故事讓你品味之后安靜的合上它的書頁,閉上眼睛不知想起為了誰流過溫?zé)岬臏I。是...
    狐生閱讀 573評(píng)論 0 2

友情鏈接更多精彩內(nèi)容