iOS - Block變量截獲

Block技術(shù)合集
Block的寫法及使用
iOS - __block 修飾符底層探索

先看代碼

static int number1 = 10; //全局靜態(tài)變量

// Block捕獲變量
- (void)captureVariableBlock {
    
    static int number2 = 10;     //局部靜態(tài)變量
    int number3 = 10;            //局部變量
    __block int number4 = 10;    //__block修飾的局部變量
    NSMutableArray *array = [NSMutableArray arrayWithObjects:@"obj1",@"obj2", nil];
    void(^captureBlock)(void) = ^ {
        NSLog(@"capture Variable \n number1 = %d, \n number2 = %d, \n number3 = %d, \n number4 = %d, \n array = %@", number1, number2, number3, number4, array);
        [array addObject:@"obj4"];
    };
    number1 = 2;
    number2 = 2;
    number3 = 2;
    number4 = 2;
    [array addObject:@"obj3"];
    array = nil;
    captureBlock();
}
}

打印結(jié)果:

2021-05-01 17:39:26.836630+0800 BlockDemo[14620:6891187] capture Variable 
 number1 = 2, 
 number2 = 2, 
 number3 = 10, 
 number4 = 2, 
 array = (
    obj1,
    obj2,
    obj3
)

通過終端命令xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc ViewController.m -o ViewController.cpp獲取編譯后的.cpp文件曼月,經(jīng)整理簡化后如下:

struct __ViewController__captureVariableBlock_block_impl_0 {
  struct __block_impl impl;
  struct __ViewController__captureVariableBlock_block_desc_0* Desc;
  int *number2;
  int number3;
  NSMutableArray *array;
  __Block_byref_number4_2 *number4; // by ref
  __ViewController__captureVariableBlock_block_impl_0(void *fp, struct __ViewController__captureVariableBlock_block_desc_0 *desc, int *_number2, int _number3, NSMutableArray *_array, __Block_byref_number4_2 *_number4, int flags=0) : number2(_number2), number3(_number3), array(_array), number4(_number4->__forwarding) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

查看__ViewController__captureVariableBlock_block_impl_0結(jié)構(gòu)體中商模,int *_number2, int _number3, NSMutableArray *_array, __Block_byref_number4_2 *_number4,,
注意:impl.isa = &_NSConcreteStackBlock 說明該block是棧block
可見疏唾,對于

  • oc對象 NSMutableArray *_array,捕獲指針
  • 局部靜態(tài)變量int *_number2捕獲指針
  • 局部變量 int _number3捕獲值
  • 全局變量并未捕獲
  • __block修飾的變量也是以指針形式捕獲的,并且生成了一個新的結(jié)構(gòu)體
struct __Block_byref_number4_2 {
  void *__isa;
__Block_byref_number4_2 *__forwarding;
 int __flags;
 int __size;
 int number4;
};

該結(jié)構(gòu)體有個熟悉int number4,即我們用__block修飾的變量
這里__forwarding是指向自身的(棧Block)
一般情況下耀盗,如果我們要對block捕獲的局部變量進(jìn)行賦值操作需要添加__block修飾符调鬓,而對全局變量,靜態(tài)變量是不需要添加__block修飾符的(全局變量不需捕獲补憾,靜態(tài)變量會捕獲指針)
另外漫萄,block里訪問self或self成員變量都會去截獲self

可以看出,局部變量的值是block定義時的值盈匾,而不是block執(zhí)行時的值

block在實現(xiàn)時就會對它引用到的它所在方法中定義的棧變量進(jìn)行一次只讀拷貝腾务,然后在block內(nèi)部使用該只讀拷貝。換句話說削饵,block截獲自動變量的初始值岩瘦,或者block捕獲的是自動變量的副本
由于blick捕獲了自動變量的瞬時值,所以在執(zhí)行block語法后窿撬,即使改寫block使用的自動變量的值也不會影響block執(zhí)行時自動變量的值启昧,所以上面局部變量的值打印是10

捕獲特性

全局變量靜態(tài)全局變量不捕獲劈伴,直接取值

局部變量基本數(shù)據(jù)類型時密末,捕獲值
局部變量oc對象時,連同所有權(quán)修飾符一起捕獲
局部靜態(tài)變量,捕獲其指針(上述numer2打印為10)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末严里,一起剝皮案震驚了整個濱河市新啼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌田炭,老刑警劉巖师抄,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異教硫,居然都是意外死亡叨吮,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進(jìn)店門瞬矩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來茶鉴,“玉大人,你說我怎么就攤上這事景用『#” “怎么了?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵伞插,是天一觀的道長割粮。 經(jīng)常有香客問我,道長媚污,這世上最難降的妖魔是什么舀瓢? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮耗美,結(jié)果婚禮上京髓,老公的妹妹穿的比我還像新娘。我一直安慰自己商架,他們只是感情好堰怨,可當(dāng)我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蛇摸,像睡著了一般备图。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赶袄,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天诬烹,我揣著相機(jī)與錄音,去河邊找鬼弃鸦。 笑死绞吁,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的唬格。 我是一名探鬼主播家破,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼颜说,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了汰聋?” 一聲冷哼從身側(cè)響起门粪,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎烹困,沒想到半個月后玄妈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡髓梅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年拟蜻,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片枯饿。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡酝锅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奢方,到底是詐尸還是另有隱情搔扁,我是刑警寧澤,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布蟋字,位于F島的核電站稿蹲,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏鹊奖。R本人自食惡果不足惜苛聘,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嫉入。 院中可真熱鬧焰盗,春花似錦璧尸、人聲如沸咒林。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽垫竞。三九已至,卻和暖如春蛀序,著一層夾襖步出監(jiān)牢的瞬間欢瞪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工徐裸, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留遣鼓,地道東北人。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓重贺,卻偏偏與公主長得像骑祟,于是被迫代替她去往敵國和親回懦。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,507評論 2 359

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