Block源碼解析

block源碼

源碼

如圖所示一個正常block底層被編譯成了 __main_block_impl_0結構體蹈垢,該結構體里包括 _block_impl里面存儲的是block的調用信息捉貌,__main_block_desc_0表示的是block內存描述肋乍。
剩下的屬性即為block里引用到的屬性

typedef void (^Block)(void);

Block block;
{
    int val = 0;
    block = ^(){
        NSLog(@"val = %d",val);
    };
}
block();

///底層被編譯成以下4個結構體
struct __block_impl {
    void *isa;
    int Flags;
    int Reserved;
    void *FuncPtr;
};

struct __main_block_impl_0 { ///block對象
    struct __block_impl impl;
    struct __main_block_desc_0 *Desc;

    __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc,int flags=0){
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
}
};

struct void __main_block_func_0(struct __main_block_impl_0 *__cself){
    printf("Block\n");
}

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)
};

一共是四個結構體汉匙,一個block對象被編譯為了一個__main_block_impl_0類型的結構體尸昧。這個結構體由兩個成員結構體和一個構造函數(shù)組成偎行。兩個結構體分別是__block_impl和__main_block_desc_0類型的枉层。其中__block_impl結構體中有一個函數(shù)指針,指針將指向__main_block_func_0類型的結構體届宠∷嘎洌總結了一副關系圖

為何block不能修改auto變量的值

當block需要截獲自動變量的時候乘粒,首先會在__main_block_impl_0結構體中增加一個成員變量并且在結構體的構造函數(shù)中對變量賦值。以上這些對應著block對象的定義伤塌。

在block被執(zhí)行的時候灯萍,把__main_block_impl_0結構體,也就是block對象作為參數(shù)傳入__main_block_func_0結構體中每聪,取出其中的val的值旦棉,進行接下來的操作

struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0 *Desc;
int val;
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc,int _val, int flags=0) : val(_val){
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
struct void __main_block_func_0(struct __main_block_impl_0 *__cself){
int val = __cself->val;
printf("val = %d",val);
}

加粗部分我理解是他是對改屬性進行了引用因此如果改變的話無法讓外部的auto變量生效

如何讓block可以修改auto變量的值

加__block修飾药薯,

編譯器會將__block變量包裝成一個結構體__Block_byref_age_0绑洛,結構體內部*__forwarding是指向自身的指針,內部還存儲著外部auto變量的值
__block的forwarding指針如下圖:

__block的源碼被編譯成了一個 ** __Block_byref_val_0**結構體童本,當block在棧上的時候他的fowarding指針指向他自己真屯,如果block被拷貝到堆里的時候他的指針會指向堆區(qū)block的指針,堆區(qū)block的fowarding指針也指向他自己因此就能保證

struct __Block_byref_val_0 {
void *__isa;
__Block_byref_val_0 *forwarding;
int __flags;
int __size;
int val;
};

struct __Block_byref_val_0 {
    void *__isa;
    __Block_byref_val_0 *forwarding;
    int __flags;
    int __size;
    int val;
};

struct __main_block_impl_0 {
    struct __block_impl impl;
    struct __main_block_desc_0 *Desc;
    __Block_byref_val_0 *val;

    __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc,__Block_byref_val_0 *_val, int flags=0) : val(_val->__forwrding){
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
}
};

struct void __main_block_func_0(struct __main_block_impl_0 *__cself){
    __Block_byref_val_0 *val = __cself->val;
    printf("val = %d",val->__forwarding->val);
}
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末巾陕,一起剝皮案震驚了整個濱河市讨跟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鄙煤,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件茶袒,死亡現(xiàn)場離奇詭異梯刚,居然都是意外死亡,警方通過查閱死者的電腦和手機薪寓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門亡资,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人向叉,你說我怎么就攤上這事锥腻。” “怎么了母谎?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵瘦黑,是天一觀的道長。 經(jīng)常有香客問我奇唤,道長幸斥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任咬扇,我火速辦了婚禮甲葬,結果婚禮上,老公的妹妹穿的比我還像新娘懈贺。我一直安慰自己经窖,他們只是感情好坡垫,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著画侣,像睡著了一般冰悠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上棉钧,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天屿脐,我揣著相機與錄音,去河邊找鬼宪卿。 笑死的诵,一個胖子當著我的面吹牛,可吹牛的內容都是我干的佑钾。 我是一名探鬼主播西疤,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼休溶!你這毒婦竟也來了代赁?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤兽掰,失蹤者是張志新(化名)和其女友劉穎芭碍,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體孽尽,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡窖壕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了杉女。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瞻讽。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖熏挎,靈堂內的尸體忽然破棺而出速勇,到底是詐尸還是另有隱情,我是刑警寧澤坎拐,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布烦磁,位于F島的核電站,受9級特大地震影響廉白,放射性物質發(fā)生泄漏个初。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一猴蹂、第九天 我趴在偏房一處隱蔽的房頂上張望院溺。 院中可真熱鬧,春花似錦磅轻、人聲如沸珍逸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谆膳。三九已至叭爱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間漱病,已是汗流浹背买雾。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工匹舞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留扛施,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓残黑,卻偏偏與公主長得像注盈,于是被迫代替她去往敵國和親晃危。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內容