帶你認(rèn)識block

一.什么是block

Block是將函數(shù)及其執(zhí)行上下文封裝起來的對象。

如下:

通過 命令編譯該.m?文件,發(fā)現(xiàn)該?block?被編譯成這個形式:


其中 WYTest是文件名赏僧, blockTest是方法名,這些可以忽略。其中__WYTest__blockTest_block_impl_0結(jié)構(gòu)體為


__block_impl?結(jié)構(gòu)體為


block內(nèi)部有?isa?指針击奶,所以說其本質(zhì)也是?OC?對象 block內(nèi)部則為:


所以說Block是將函數(shù)及其執(zhí)行上下文封裝起來的對象既然Block內(nèi)部封裝了函數(shù),那么它同樣也有參數(shù)和返回值责掏。

二柜砾、Block?變量截獲

1、局部變量截獲 是值截獲换衬。 比如:

這里的輸出是 6 而不是 2痰驱,原因就是對局部變量?num?的截獲是值截獲证芭。 同樣,在?block?里如果修改變量?num担映,也是無效的废士,甚至編譯器會報錯。


打印為 1蝇完,2官硝,3局部對象變量也是一樣,截獲的是值短蜕,而不是指針氢架,在外部將其置為 nil,對?block?沒有影響忿危,而該對象調(diào) 用方法會影響.

2达箍、局部靜態(tài)變量截獲 是指針截獲。


輸出為 2铺厨,意味著 num = 1 這里的修改 num 值是有效的缎玫,即是指針截獲。 同樣解滓,在 block 里去修改變量 m赃磨,也是有效的。

3洼裤、全局變量邻辉,靜態(tài)全局變量截獲:不截獲,直接取值。

我們同樣用?clang?編譯看下結(jié)果腮鞍。

?static NSInteger num3 = 300;

??NSInteger num4 = 3000;

編譯后


編譯后

(?impl.isa?=?&_NSConcreteStackBlock;這里注意到這一句值骇,即說明該?block?是棧?block) 可以看到局部變量被編譯成值形式,而靜態(tài)變量被編成指針形式移国,全局變量并未截獲吱瘩。而__block 修飾的變 量也是以指針形式截獲的,并且生成了一個新的結(jié)構(gòu)體對象:


該對象有個屬性:num5迹缀,即我們用 __block修飾的變量使碾。這里__forwarding?是指向自身的(棧 block)。一般情況下祝懂,如果我們要對 block 截獲的局部變量進行賦值操作需添加__block修飾符票摇,而對全局變量,靜態(tài)變量是不需要添加__block修飾符的砚蓬。 另外矢门,block?里訪問?self?或成員變量都會去截獲。

三、Block?的幾種形式

分為全局Block(_NSConcreteGlobalBlock)颅和、棧Block(_NSConcreteStackBlock)傅事、堆Block(_NSConcreteMallocBlock)三種形式其中棧 Block 存儲在棧(stack)區(qū),堆?Block?存儲在堆(heap)區(qū)峡扩,全局?Block?存儲在已初始化數(shù)據(jù)(.data)區(qū)

1、不使用外部變量的?block?是全局?block

比如:


全局block

輸出:


輸出

2障本、使用外部變量并且未進行?copy?操作的?block?是棧?block

比如:


棧block

輸出:


輸出

3教届、對棧?block?進行?copy?操作,就是堆?block驾霜,而對全局?block?進行?copy案训,仍是全局?block

比如堆1中的全局進行copy操作,即賦值:


賦值

輸出:


仍是全局block

而對2中的棧block進行賦值操作:

棧block進行賦值

輸出:


成了堆block

對棧?blockcopy?之后粪糙,并不代表著棧?block?就消失了强霎,左邊的?mallock?是堆?block,右邊被?copy?的仍是棧?block蓉冈。比如:


輸出:


輸出

即如果對棧 進行copy城舞,將會copy到堆區(qū),對堆Block進行copy寞酿,將會增加引用計數(shù)家夺,對全局Block?進行 copy,因為是已經(jīng)初始化的伐弹,所以什么也不做拉馋。

另外,__block 變量在 時惨好,由于__forwarding?的存在煌茴,棧上的 指針會指向堆上的 g 變量,而堆上的 指針指向其自身日川,所以蔓腐,如果對 的修改,實際上是在修改堆上的 __block 變量逗鸣。

即__forwarding?指針存在的意義就是合住,無論在任何內(nèi)存位置,都可以順利地訪問同一個__block?變量撒璧。另外由于block捕獲的 修飾的變量會去持有變量透葛,那么如果用__block修飾self,且self持有Block卿樱,并且 block 內(nèi)部使用到__block修飾的self時僚害,就會造成多循環(huán)引用,即?self?持有?block,block 持有__block變量 萨蚕,__block變量持有self靶草,造成內(nèi)存泄漏。

如果要解決這種循環(huán)引用岳遥,可以主動斷開__block變量對self的持有奕翔,即block內(nèi)部使用完weakself后將其置為 nil,但這種方式有個問題浩蓉,如果 一直不被調(diào)用派继,那么循環(huán)引用將一直存在。 所以捻艳,我們最好還是用__weak?來修飾.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末驾窟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子认轨,更是在濱河造成了極大的恐慌绅络,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘁字,死亡現(xiàn)場離奇詭異恩急,居然都是意外死亡,警方通過查閱死者的電腦和手機拳锚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門假栓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人霍掺,你說我怎么就攤上這事匾荆。” “怎么了杆烁?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵牙丽,是天一觀的道長。 經(jīng)常有香客問我兔魂,道長烤芦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任析校,我火速辦了婚禮构罗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘智玻。我一直安慰自己遂唧,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布吊奢。 她就那樣靜靜地躺著盖彭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上召边,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天铺呵,我揣著相機與錄音,去河邊找鬼隧熙。 笑死片挂,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的贞盯。 我是一名探鬼主播宴卖,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼邻悬!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起随闽,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤父丰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后掘宪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛾扇,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年魏滚,在試婚紗的時候發(fā)現(xiàn)自己被綠了镀首。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡鼠次,死狀恐怖更哄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情腥寇,我是刑警寧澤成翩,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站赦役,受9級特大地震影響麻敌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜掂摔,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一术羔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧乙漓,春花似錦级历、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春扛禽,著一層夾襖步出監(jiān)牢的瞬間锋边,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工编曼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留豆巨,地道東北人。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓掐场,卻偏偏與公主長得像往扔,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子熊户,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,092評論 2 355

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