Objective-C的Block實(shí)質(zhì)與實(shí)現(xiàn)探究 part-2

Block截獲自動(dòng)變量的情況

</br>
Objective-C語句:

int main() {
    int dmy = 256;
    int val = 10;  
    const char *fmt = "val = %d\n";
    
    void (^blk)(void) = ^{ printf(fmt, val); };
  
    val = 2;
    fmt = "These values were changed. val = %d\n";
    
    blk();

    return 0;
}

C++源碼:(注:有一部分與上例相同的代碼已省略)

struct __main_block_impl_0 {
    struct __block_impl impl;
    struct __main_block_desc_0 *Desc;
    const char *fmt;
    int val;

    __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, const char *_fmt, int _val, int flags=0) : fmt(_fmt), val(_val) {
        impl.isa = &_NSConcreteStackBlock;
        impl.Flags = flags;
        impl.FuncPtr = fp;
        Desc = desc;
    }
};

static void __main_block_func_0 (struct __main_block_impl_0 *__cself) {
    const char *fmt = __cself->fmt;
    int val = __cself->val;
    
    printf(fmt, val);
}

static struct __main_block_desc_0 {
    unsigned long reserved;
    unsigned long Block_size;
}    __main_block_desc_0_DATA = {
    0,
    sizeof(struct __main_block_impl_0)
};

int main() {
    int dmy = 256;
    int val = 10;
    const char *fmt = "val = %d\n";
    void (*blk)(void) = &__main_block_impl_0(__main_block_func_0, &__main_block_desc_0_DATA, fmt, val);
}
Block數(shù)據(jù)結(jié)構(gòu)圖(4)

整體看削解,__main_block_impl_0結(jié)構(gòu)體柱徙、__main_block_func_0函數(shù)整以、和main函數(shù)內(nèi)blk對(duì)構(gòu)造函數(shù)的調(diào)用都發(fā)生了改變:

  • __main_block_impl_0結(jié)構(gòu)體內(nèi)聲明的成員變量與自動(dòng)變量的類型完全相同const char *int。同時(shí)發(fā)現(xiàn)很重要的一點(diǎn)棵帽,dmy變量沒有被追加到__main_block_impl_0結(jié)構(gòu)體的成員變量中通铲。為什么?因?yàn)锽lock沒有使用它片任。由此得知偏友,Block對(duì)自動(dòng)變量的截獲只針對(duì)會(huì)在Block內(nèi)使用的自動(dòng)變量。 同時(shí)对供,該結(jié)構(gòu)體的構(gòu)造函數(shù)也對(duì)截獲的自動(dòng)變量追加的成員變量進(jìn)行了初始化操作位他。
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, const char *_fmt, int _val, int flags=0) : fmt(_fmt), val(_val)  { ... }
  • main函數(shù)內(nèi)的構(gòu)造函數(shù)調(diào)用中也添加了相應(yīng)的參數(shù)
void (*blk)(void) = &__main_block_impl_0(__main_block_func_0, &__main_block_desc_0_DATA, fmt, val)
  • __main_block_func_0函數(shù)
static void __main_block_func_0 (struct __main_block_impl_0 *__cself) {
    const char *fmt = __cself->fmt;
    int val = __cself->val;
    
    printf(fmt, val);
}

由于在mainblk調(diào)用構(gòu)造函數(shù)時(shí)已經(jīng)截獲到自動(dòng)變量,并被保存到Block結(jié)構(gòu)體的實(shí)例中产场,所以可以直接使用__cself->fmt__cself->val鹅髓。

至此,可以解釋兩件事情:

第一京景,為什么在Block截獲了自動(dòng)變量之后窿冯,在外部修改自動(dòng)變量的值,不會(huì)影響B(tài)lock截獲到的值醋粟。
答:見代碼注釋部分的文字靡菇。

int dmy = 256;
int val = 10;  
const char *fmt = "val = %d\n";
    
void (^blk)(void) = ^{ printf(fmt, val); };   //此處完成自動(dòng)變量的截獲
  
val = 2;              //在Block外修改自動(dòng)變量的值重归,不會(huì)影響B(tài)lock內(nèi)已經(jīng)保存的值
fmt = "These values were changed. val = %d\n";
    
blk();

第二,為什么Block截獲的自動(dòng)變量不能被改寫厦凤。
答:因?yàn)樵趯?shí)現(xiàn)上不能改寫被截獲自動(dòng)變量的值鼻吮。

int val = 0;
void (^blk)(void) = ^{ val = 1; };

我們知道賦值語句^{ val = 1; }實(shí)際上是在調(diào)用Block的構(gòu)造函數(shù),但是在實(shí)現(xiàn)構(gòu)造函數(shù)中并沒有參數(shù)位置可以保存這個(gè)要賦值給val1较鼓。對(duì)于這種行為椎木,編譯器在編譯過程會(huì)檢測(cè)出,從而產(chǎn)生編譯錯(cuò)誤博烂。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末香椎,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子禽篱,更是在濱河造成了極大的恐慌畜伐,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件躺率,死亡現(xiàn)場(chǎng)離奇詭異玛界,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)悼吱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門慎框,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人后添,你說我怎么就攤上這事笨枯。” “怎么了遇西?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵馅精,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我努溃,道長(zhǎng)硫嘶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任梧税,我火速辦了婚禮沦疾,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘第队。我一直安慰自己哮塞,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布凳谦。 她就那樣靜靜地躺著忆畅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪尸执。 梳的紋絲不亂的頭發(fā)上家凯,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天缓醋,我揣著相機(jī)與錄音,去河邊找鬼绊诲。 笑死送粱,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的掂之。 我是一名探鬼主播抗俄,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼世舰!你這毒婦竟也來了动雹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤跟压,失蹤者是張志新(化名)和其女友劉穎胰蝠,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體裆馒,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡姊氓,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了喷好。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡读跷,死狀恐怖梗搅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情效览,我是刑警寧澤无切,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站丐枉,受9級(jí)特大地震影響哆键,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瘦锹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一籍嘹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧弯院,春花似錦辱士、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至椅挣,卻和暖如春头岔,著一層夾襖步出監(jiān)牢的瞬間塔拳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工峡竣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蝙斜,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓澎胡,卻偏偏與公主長(zhǎng)得像孕荠,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子攻谁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

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