Block

1版述、什么是局部變量,什么是全局變量

? ? 局部變量分為自動(dòng)變量(就是我們平常在函數(shù)內(nèi)部定義的變量,只是默認(rèn)省略了auto修飾符)和靜態(tài)變量(在函數(shù)內(nèi)部定義悴务,用static修飾),局部變量之所以稱(chēng)為局部變量譬猫,是因?yàn)槌隽俗饔糜蚓蜁?huì)銷(xiāo)毀讯檐,但是static修飾的局部變量會(huì)一直在內(nèi)存中。

2染服、Block的本質(zhì)就是一個(gè)OC對(duì)象别洪,他有isa指針,并且Block是封裝了函數(shù)以及函數(shù)調(diào)用環(huán)境的OC對(duì)象? ?Block轉(zhuǎn)化成的結(jié)構(gòu)體中都擁有impl(里面包含了封裝函數(shù)的地址)和desc(這里包括了這個(gè)Block的size 保留對(duì)象柳刮, copy方法挖垛,這個(gè)方法是用來(lái)將block從棧拷貝到堆中使用的秉颗,還有dispose方法痢毒,這個(gè)方法是block銷(xiāo)毀的時(shí)候調(diào)用的,copy和dispose方法只有自動(dòng)變量是對(duì)象類(lèi)型的時(shí)候才會(huì)出現(xiàn)蚕甥,因?yàn)橹挥袑?duì)象類(lèi)型才需要進(jìn)行內(nèi)存操作)


3哪替、為了保證Block能夠訪問(wèn)外部的變量,Block有個(gè)外部變量捕獲機(jī)制梢灭,自動(dòng)變量和靜態(tài)變量都會(huì)被Block捕獲夷家,但是自動(dòng)變量是值捕獲,就是值存自動(dòng)變量的值敏释,但是靜態(tài)變量是指針捕獲库快,因?yàn)榻鹛┳兞恳恢痹趦?nèi)存中,所以可以直接調(diào)用就行钥顽,所以是指針捕獲义屏。捕獲局部變量的原因是自動(dòng)變量出了作用域就銷(xiāo)毀了,可是Block出了函數(shù)作用域還可以在別的函數(shù)中調(diào)用蜂大,而你封裝的Block內(nèi)部又訪問(wèn)了你已經(jīng)銷(xiāo)毀的局部變量闽铐,所以Block內(nèi)部必須把局部變量通過(guò)值捕獲或者指針捕獲保存在Block內(nèi)部

4、Block不會(huì)捕獲全局變量奶浦,因?yàn)槿肿兞康教幎寄茉L問(wèn)兄墅,跨函數(shù)也能訪問(wèn),所以根本沒(méi)必要再在Block內(nèi)部保存一份了澳叉,直接訪問(wèn)就可以了


Block捕獲變量圖??

5隙咸、需要注意的是? 如果Block內(nèi)部訪問(wèn)了self沐悦,那么這個(gè)self也會(huì)被捕獲,原因是self也是個(gè)局部變量五督,因?yàn)榉椒ㄞD(zhuǎn)換成C語(yǔ)言函數(shù)之后 都會(huì)變成XXX(self,_cmd),也就是說(shuō)方法轉(zhuǎn)換成C語(yǔ)言后都有固定的兩個(gè)參數(shù)藏否,一個(gè)是self,另一個(gè)是方法名稱(chēng)充包,作為參數(shù)副签,那么久肯定是局部變量,所以肯定會(huì)被捕獲

Block的類(lèi)型

1基矮、Block都是繼承自NSBlock類(lèi)型的淆储,Block分為_(kāi)_GlobalBlock__? ?、__ NSStackBlock__ 家浇、__ NSMallocBlock__三種類(lèi)型遏考,其中__GlobalBlock__ 存放在數(shù)據(jù)區(qū)、__ NSStackBlock__存放在棧區(qū)蓝谨、__ NSMallocBlock__存放在堆區(qū)

2、只要你不訪問(wèn)自動(dòng)變量青团,那么Block類(lèi)型就是__GlobalBlock__ 如果你訪問(wèn)了自動(dòng)變量譬巫,在MRC上你就會(huì)是__ NSStackBlock__類(lèi)型,但是在ARC上督笆,有下面4中情況芦昔,系統(tǒng)會(huì)自動(dòng)把BLock copy一份到堆中

????2.1、使用copy方法

? ? 2.2娃肿、賦值給strong指針

? ??2.3咕缎、block作為方法名字中含有UnsignBlock的方法參數(shù)(比如枚舉邊里數(shù)組)

????2.4、block作為作為GCD的方法參數(shù)? ?

這4中情況下Block就是__ NSMallocBlock__料扰,其余的 只要你沒(méi)有訪問(wèn)自動(dòng)變量凭豪,那就是__GlobalBlock__ ,訪問(wèn)了晒杈,那么你就是__ NSStackBlock__

3嫂伞、如果Block訪問(wèn)了自動(dòng)變量,但是你的這個(gè)Block只是棧上面的Block拯钻,那么這個(gè)Block內(nèi)部就不會(huì)堆自動(dòng)變量進(jìn)行引用帖努,強(qiáng)弱引用都不會(huì),因?yàn)锽lock都會(huì)隨時(shí)不保粪般,引用自動(dòng)變量也沒(méi)有多大意義拼余。如果Block被拷貝到了堆上面,那么就會(huì)調(diào)用Block內(nèi)部的Copy方法亩歹,copy法法內(nèi)部就會(huì)調(diào)用_Block_object_assign函數(shù)匙监,會(huì)根據(jù)自動(dòng)變量是weak類(lèi)型凡橱,還是strong類(lèi)型還是unsafe_unretained類(lèi)型,來(lái)對(duì)該自動(dòng)變量進(jìn)行強(qiáng)弱引用舅柜。當(dāng)Block銷(xiāo)毀的時(shí)候梭纹,會(huì)調(diào)用Block內(nèi)部的dispose方法,根據(jù)_Block_object_dispose函數(shù)來(lái)對(duì)已經(jīng)引用的自動(dòng)變量進(jìn)行釋放

Block修改自動(dòng)變量

? ? 1.block訪問(wèn)了自動(dòng)變量致份,自動(dòng)變量只是值傳遞变抽,如果你要在block內(nèi)部就改變不了這個(gè)自動(dòng)變量的值

? ? 2、但是如果你的自動(dòng)變量是指針傳遞氮块,那么因?yàn)槟愕膬?nèi)部引用了該指針绍载,所以你就能改變這個(gè)指針?biāo)笇?duì)象的值(static修飾的局部變量,全局變量)

? ? 3滔蝉、如果不能修改自動(dòng)變量击儡,你需要用__block來(lái)修飾該自動(dòng)變量,__block內(nèi)部是將該自動(dòng)變量包裝成了一個(gè)新的對(duì)象蝠引,這個(gè)新的對(duì)象中有個(gè)指向自己的指針阳谍,如果你要修改該自動(dòng)變量,他就會(huì)通過(guò)forwarding指針找到被包裝的這個(gè)對(duì)象螃概,然后修改里面的值


Block修改被__block修飾的對(duì)象

4矫夯、為什么非要弄一個(gè)forwarding指針來(lái)指向自己呢,為什么不通過(guò)Block內(nèi)部指向結(jié)構(gòu)體的指針找到你要修改的自動(dòng)變量來(lái)進(jìn)行修改呢

? ? 答:因?yàn)樽詣?dòng)變量生成的時(shí)候都是在棧區(qū)的吊洼,通過(guò)Block的自動(dòng)捕獲機(jī)制训貌,還有用__block修飾之后,把你的這個(gè)自動(dòng)變量包裝成了一個(gè)結(jié)構(gòu)體冒窍,Block內(nèi)部的指向結(jié)構(gòu)體的指針指向了這個(gè)結(jié)構(gòu)體递沪,Block一旦被copy到了堆區(qū),那么這個(gè)結(jié)構(gòu)體也被復(fù)制到了堆區(qū)综液,會(huì)調(diào)用block內(nèi)部的copy函數(shù)款慨,copy函數(shù)內(nèi)部會(huì)調(diào)用_Block_object_assign函數(shù),_Block_object_assign函數(shù)會(huì)對(duì)__block變量形成強(qiáng)引用(根據(jù)變量修飾符來(lái)決定)谬莹,但是我們修改變量后樱调,我們都希望只對(duì)堆取得自動(dòng)變量進(jìn)行修改,因?yàn)樾薷臈^(qū)的沒(méi)意義届良,但是吐過(guò)你訪問(wèn)的是戰(zhàn)區(qū)的自動(dòng)變量笆凌,然后修改了,那就達(dá)不到效果了士葫,這個(gè)時(shí)候乞而,就需要指向自己的指針了,如果你訪問(wèn)的是站上的自動(dòng)變量慢显,站上的自動(dòng)變量的forwarding指針指向的是堆中的__block包裝的結(jié)構(gòu)體爪模,然后再堆中的結(jié)構(gòu)體找到forwarding找到堆中結(jié)構(gòu)體里面的自動(dòng)變量進(jìn)行修改欠啤,如果你修改的是堆中的自動(dòng)變量,那就直接找到堆中的結(jié)構(gòu)體進(jìn)行修改屋灌,所以forwarding的作用就是無(wú)論你修改的是占中的自動(dòng)變量還是堆中的洁段,都能保證修改了堆中的自動(dòng)變量


forwarding指針

5、Block在棧上時(shí)共郭,并不會(huì)對(duì)__block變量進(jìn)行強(qiáng)引用祠丝,當(dāng)block被copy到堆時(shí)會(huì)調(diào)用block內(nèi)部的copy函數(shù),copy函數(shù)內(nèi)部會(huì)調(diào)用_Block_object_assign函數(shù)除嘹,_Block_object_assign函數(shù)會(huì)對(duì)__block變量形成強(qiáng)引用(非對(duì)象類(lèi)型写半,對(duì)象類(lèi)型還要根據(jù)修飾符決定是否強(qiáng)引用,如果是MRC? 那么一定是弱引用)

6尉咕、當(dāng)block從堆中移除時(shí)叠蝇,會(huì)調(diào)用block內(nèi)部的dispose函數(shù),dispose函數(shù)內(nèi)部會(huì)調(diào)用_Block_object_dispose函數(shù)年缎,_Block_object_dispose函數(shù)會(huì)自動(dòng)釋放引用的__block變量(release)


ARC循環(huán)引用問(wèn)題圖解


MRC下循環(huán)應(yīng)用問(wèn)題
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末悔捶,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子单芜,更是在濱河造成了極大的恐慌炎功,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缓溅,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡赁温,警方通過(guò)查閱死者的電腦和手機(jī)坛怪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)股囊,“玉大人袜匿,你說(shuō)我怎么就攤上這事≈烧睿” “怎么了居灯?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)内狗。 經(jīng)常有香客問(wèn)我怪嫌,道長(zhǎng),這世上最難降的妖魔是什么柳沙? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任岩灭,我火速辦了婚禮,結(jié)果婚禮上赂鲤,老公的妹妹穿的比我還像新娘噪径。我一直安慰自己柱恤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布找爱。 她就那樣靜靜地躺著梗顺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪车摄。 梳的紋絲不亂的頭發(fā)上寺谤,一...
    開(kāi)封第一講書(shū)人閱讀 51,190評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音练般,去河邊找鬼矗漾。 笑死,一個(gè)胖子當(dāng)著我的面吹牛薄料,可吹牛的內(nèi)容都是我干的敞贡。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼摄职,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼誊役!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起谷市,我...
    開(kāi)封第一講書(shū)人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蛔垢,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后迫悠,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體鹏漆,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年创泄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了艺玲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鞠抑,死狀恐怖饭聚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情搁拙,我是刑警寧澤秒梳,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站箕速,受9級(jí)特大地震影響酪碘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜盐茎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一婆跑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧庭呜,春花似錦滑进、人聲如沸犀忱。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)阴汇。三九已至,卻和暖如春节槐,著一層夾襖步出監(jiān)牢的瞬間搀庶,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工铜异, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留哥倔,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓揍庄,卻偏偏與公主長(zhǎng)得像咆蒿,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蚂子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容