《Objective-C高級編程》Blocks 閱讀筆記 item6(__block變量存儲域)

《Objective-C高級編程》Blocks 閱讀筆記系列

《Objective-C高級編程》Blocks 閱讀筆記 item1(Blocks概要和模式)
《Objective-C高級編程》Blocks 閱讀筆記 item2(Block的實質)
《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循環引用)
《Objective-C高級編程》Blocks 閱讀筆記 item10(copy/release實例方法)

2.3 Blocks的實現

2.3.5 __block變量存儲域

從“Block存儲域”一節可知,*** 使用__block變量的Block從棧復制到堆上時,__block變量也會受到影響。 ***
表 Block從棧復制到堆時對__block變量產生的影響

__block變量的配置存儲域 Block從棧復制到堆時的影響
從棧復制到堆并被Block持有
被Block持有

*** 在一個Block中使用__block變量 ***

Snip20160217_20.png

*** 在多個Block中使用__block變量 ***

Snip20160217_21.png

*** Block的廢棄和__block變量的釋放 ***

Snip20160217_22.png

遺留的問題

“Block存儲域”一節中遺留的問題:

  • 使用__block變量的結構體成員變量__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無關的__block變量 ***

++val;

然而,以上兩種源代碼都可以轉換為:

++(val.__forwaring->val);

在變化Block語法的函數中,該變量val為 *** 復制到堆上的__block變量的結構體實例 ,而使用與Block無關的變量val,為 復制前棧上的__block變量的結構體實例 ***。

但是,棧上的__block變量的結構體實例(即變量val)在__block變量從棧復制到堆上時,會將成員變量__forwarding的值替換為復制目標堆上的__block變量的結構體實例的地址

Snip20160217_24.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容