Ios復(fù)習(xí)--Block的使用

Block 是一種特殊的數(shù)據(jù)類型,默認(rèn)存儲(chǔ)在棧中,若對(duì)Block 進(jìn)行一次Copy 則Block會(huì)進(jìn)入堆中

1.Block訪問外部參數(shù)變量

--1.Block中可以訪問外界變量,會(huì)將外界變量Copy一份,供自己訪問,并不能修改外界變量的值,同理,由于是Copy一份,則在Blcok調(diào)用之前修改外界參數(shù)的值,同樣不會(huì)影響到Block內(nèi)部堆參數(shù)的引用,該值只是在Block聲明時(shí)有效

證明block中的參數(shù)是copy進(jìn)該block的堆中

--2.Block 中可以定義和外界同名的變量,并且若在block中定義了和外界同名的變量,在Block中訪問的是Block中的變量

2.__block 修飾符

--1.要在Block中修改外界參數(shù),需要用__block 修飾該參數(shù)

但是,若在Block中修改了外界變量的值,會(huì)影響到外界變量的值

--2.__Block 可以防止Block在堆中時(shí),對(duì)外部參數(shù)引用后Retain操作

3.__Block 關(guān)鍵字的實(shí)現(xiàn)原理

將代碼通過 終端 編譯成 c++代碼后發(fā)現(xiàn),在不加__Block關(guān)鍵字時(shí),Block 在底層會(huì)被編譯成結(jié)構(gòu)體,而參數(shù)a 是通過參數(shù)傳遞進(jìn)結(jié)構(gòu)體函數(shù),并將該參數(shù),賦值給結(jié)構(gòu)體內(nèi)部的變量a

既 如果沒有添加__block 關(guān)鍵字聲明變量 該變量是值傳遞

內(nèi)部函數(shù)的調(diào)用

a變量的具體引用

添加__block關(guān)鍵字 后是對(duì)a變量地址的引用

添加__block關(guān)鍵字后,是對(duì)a變量地址的引用

4.MRC中的Block引用計(jì)數(shù)

默認(rèn)情況下block 存儲(chǔ)在棧中,如果對(duì)block 進(jìn)行一個(gè)copy操作,block 會(huì)轉(zhuǎn)移到堆中,

若block在棧中,且訪問了外界的對(duì)象,不會(huì)對(duì)對(duì)象進(jìn)行retain操作

但是,若block在堆中,且訪問了外界對(duì)象,那么會(huì)外界的對(duì)象進(jìn)行一次retain操作

需要通過Block_release()函數(shù)在dealloc函數(shù)中對(duì)Block 進(jìn)行釋放 ,block中使用到的對(duì)象也都會(huì)收到該消息


在實(shí)際開發(fā)中,若在Block 中訪問了外界對(duì)象,一定要給變量添加__block 修飾符,這樣哪怕Block在堆中,也不會(huì)對(duì)外界對(duì)象進(jìn)行Retain

5.copy Block 引發(fā)的循環(huán)引用

--1.MRC下

在堆中的Block內(nèi),引用自己對(duì)象本身,形成循環(huán)引用 利用 __block 修飾對(duì)象,在block內(nèi)不會(huì)進(jìn)行retain

在堆中的Block內(nèi),引用自己對(duì)象本身,形成循環(huán)引用 利用 __block 修飾對(duì)象,在block內(nèi)不會(huì)進(jìn)行retain

--2.ARC

在ARC環(huán)境中同理,被Copy的Block 在堆中,會(huì)對(duì)引用的外界參數(shù)進(jìn)行強(qiáng)引用,這個(gè)時(shí)候需要將傳入Block內(nèi)的對(duì)象,轉(zhuǎn)化為若引用即可

Friend *p = [[Friend alloc]init];

下面這兩句代碼任選一句就可以了,但是官方推薦選用第一句

__weak typeof (p) weakp = p;

__unsafe_unretained typeof (p) weaka = p ;

p.testBlock =^{

[weakp run];

};

總結(jié)

1:什么是block?

block其實(shí)就是一個(gè)代碼塊,把你想要執(zhí)行的代碼封裝在這個(gè)代碼塊里,等到需要的時(shí)候再去調(diào)用。那block是OC對(duì)象嗎?答案是肯定的

官方文檔如下

2:block要用copy修飾,還是用strong

block本身是像對(duì)象一樣可以retain,和release。但是,block在創(chuàng)建的時(shí)候,它的內(nèi)存是分配在棧(stack)上,而不是在堆(heap)上。他本身的作于域是屬于創(chuàng)建時(shí)候的作用域,一旦在創(chuàng)建時(shí)候的作用域外面調(diào)用block將導(dǎo)致程序崩潰。

使用retain也可以,但是block的retain行為默認(rèn)是用copy的行為實(shí)現(xiàn)的,

因?yàn)閎lock變量默認(rèn)是聲明為棧變量的,為了能夠在block的聲明域外使用,所以要把block拷貝(copy)到堆,所以說(shuō)為了block屬性聲明和實(shí)際的操作一致,最好聲明為copy。

3:__block關(guān)鍵字的使用

在Block的{}體內(nèi),是不可以對(duì)外面的變量進(jìn)行更改的,使用__block就能改變block塊中變量的值

4:__block和__weak有什么區(qū)別?

__block不管是ARC還是MRC模式下都可以使用,可以修飾對(duì)象,還可以修飾基本數(shù)據(jù)類型。__weak只能在ARC模式下使用,也只能修飾對(duì)象(NSString),不能修飾基本數(shù)據(jù)類型(int)。__block對(duì)象可以在block中被重新賦值,__weak不可以。

最后編輯于
?著作權(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)容

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