《Objective-C高級編程》Blocks 閱讀筆記系列
《Objective-C高級編程》Blocks 閱讀筆記 item1(Blocks概要和模式)
《Objective-C高級編程》Blocks 閱讀筆記 item2(Block的實質(zhì))
《Objective-C高級編程》Blocks 閱讀筆記 item3(截獲自動變量值)
《Objective-C高級編程》Blocks 閱讀筆記 item4(__block說明符)
《Objective-C高級編程》Blocks 閱讀筆記 item5(Block存儲域)
《Objective-C高級編程》Blocks 閱讀筆記 item6(__block變量存儲域)
《Objective-C高級編程》Blocks 閱讀筆記 item7(截獲對象)
《Objective-C高級編程》Blocks 閱讀筆記 item8(__block變量和對象)
《Objective-C高級編程》Blocks 閱讀筆記 item9(Block循環(huán)引用)
《Objective-C高級編程》Blocks 閱讀筆記 item10(copy/release實例方法)
2.3 Blocks的實現(xiàn)
2.3.5 __block變量存儲域
從“Block存儲域”一節(jié)可知脊凰,*** 使用__block變量的Block從棧復制到堆上時抖棘,__block變量也會受到影響。 ***
表 Block從棧復制到堆時對__block變量產(chǎn)生的影響
__block變量的配置存儲域 | Block從棧復制到堆時的影響 |
---|---|
棧 | 從棧復制到堆并被Block持有 |
堆 | 被Block持有 |
*** 在一個Block中使用__block變量 ***
*** 在多個Block中使用__block變量 ***
*** Block的廢棄和__block變量的釋放 ***
遺留的問題
“Block存儲域”一節(jié)中遺留的問題:
- 使用__block變量的結(jié)構(gòu)體成員變量__forwarding的原因
*** 不管__block變量配置在棧上還是在堆上狸涌,都能夠正確地訪問該變量 ***
正如這句話所訴切省,通過Block的復制,__block變量也會從棧復制到堆上帕胆。此時可同時訪問棧上的__block變量和堆上的__block變量朝捆。
__block int val = 0; // __block變量
void (^blk)(void) = [^{++val;} copy]; // Block
++val;
blk();
NSLog(@"%d", val);
利用copy方法復制使用了__block變量的Block語法。此時惶楼,Block和__block變量均從棧復制到堆右蹦。
*** 在Block語法表達式中,使用初始化后的__block變量 ***
^{++val;}
*** 在Block語法表達式之后歼捐,使用與Block無關(guān)的__block變量 ***
++val;
然而何陆,以上兩種源代碼都可以轉(zhuǎn)換為:
++(val.__forwaring->val);
在變化Block語法的函數(shù)中,該變量val為 *** 復制到堆上的__block變量的結(jié)構(gòu)體實例 豹储,而使用與Block無關(guān)的變量val贷盲,為 復制前棧上的__block變量的結(jié)構(gòu)體實例 ***。
但是剥扣,棧上的__block變量的結(jié)構(gòu)體實例(即變量val)在__block變量從棧復制到堆上時巩剖,會將成員變量__forwarding的值替換為復制目標堆上的__block變量的結(jié)構(gòu)體實例的地址。