到底什么是block臂容?

簡述Block

block 是 C 語言的擴充功能,我們可以認為它是 帶有自動變量的匿名函數(shù)范删,同時也是一個對象蕾域。

  • 首先Block聲明及定義語法,及其變形
1 標準定義
returnType(^blockName)(var_type) = ^returnType(var_type varName){ //操作 }
舉個?? :
void(^defalutBlock)(NSString *) = ^void(NSString *name){ NSlog(@"%@",name)}

2 省略縮寫
returnType(^blockName)(var_type) = ^(var_type varName){ //操作 }
舉個?? :
void(^defalutBlock)(NSString *) = ^(NSString *name){ NSlog(@"%@",name)}

3 typedef簡化Block的聲明
typedef return_type (^BlockTypeName)(var_type);
  • 接下來我們看幾個面試題來分析下

1.block的原理是怎樣的瓶逃?本質(zhì)是什么?
2.__block的作用是什么廓块?有什么使用注意點厢绝?
3.block的屬性修飾詞為什么是copy?使用block有哪些使用注意带猴?
4.block在修改NSMutableArray昔汉,需不需要添加__block

問題1: block原理是什么拴清?本質(zhì)是什么靶病?

寫個block

int main(int argc, char * argv[]) {
    int(^block)(int)=^int(int a)
    {
        return  a;
    };
    block(8);
    
    return  0;
}

通過使用clang命令,將.m文件轉(zhuǎn)換成.cpp文件clang -rewrite-objc main.m

int main(int argc, char * argv[]) {

    int(*block)(int)=((int (*)(int))&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));
    ((int (*)(__block_impl *, int))((__block_impl *)block)->FuncPtr)((__block_impl *)block, 8);

    return 0;
}

C++定義block變量代碼 其中不難看出 將__main_block_impl_0函數(shù)的地址賦值給了block

 int(*block)(int)=((int (*)(int))&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));

我們接著看下__main_block_impl_0是什么口予?是一個結(jié)構(gòu)體

struct __main_block_impl_0 {
  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;
  }
};

注意:__main_block_impl_0結(jié)構(gòu)體中 有同名的構(gòu)造函數(shù)__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) 其中的fp 可以理解為方法的地址

我們可以看到__main_block_desc_0中存儲著兩個參數(shù)娄周,reserved和Block_size,并且reserved賦值為0而Block_size則存儲著__main_block_impl_0的占用空間大小沪停。最終將__main_block_desc_0結(jié)構(gòu)體的地址傳入__main_block_func_0中賦值給Desc

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

我們再來看下__block_impl結(jié)構(gòu)體

struct __block_impl {
  void *isa;
  int Flags;
  int Reserved;
  void *FuncPtr;
};

我們可以發(fā)現(xiàn)__block_impl結(jié)構(gòu)體內(nèi)部就有一個isa指針煤辨。因此可以證明block本質(zhì)上就是一個oc對象裳涛。而在構(gòu)造函數(shù)中將函數(shù)中傳入的值分別存儲在__main_block_impl_0結(jié)構(gòu)體實例中,最終將結(jié)構(gòu)體的地址賦值給block众辨。

分析得出

  1. __block_impl結(jié)構(gòu)體中isa指針存儲著&_NSConcreteStackBlock地址端三,可以暫時理解為其類對象地址,block就是_NSConcreteStackBlock類型的
  2. block代碼塊中的代碼被封裝成__main_block_func_0函數(shù)鹃彻,F(xiàn)uncPtr則存儲著__main_block_func_0函數(shù)的地址郊闯。
  3. Desc指向__main_block_desc_0結(jié)構(gòu)體對象,其中存儲__main_block_impl_0結(jié)構(gòu)體所占用的內(nèi)存蛛株。

問題總結(jié):


此時已經(jīng)基本對block的底層結(jié)構(gòu)有了基本的認識团赁,上述代碼可以通過一張圖展示其中各個結(jié)構(gòu)體之間的關(guān)系。

image

本文有參考其他作者:
block文章---xxcc

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末泳挥,一起剝皮案震驚了整個濱河市然痊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌屉符,老刑警劉巖剧浸,帶你破解...
    沈念sama閱讀 223,002評論 6 519
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異矗钟,居然都是意外死亡唆香,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,357評論 3 400
  • 文/潘曉璐 我一進店門吨艇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來躬它,“玉大人,你說我怎么就攤上這事东涡》胂牛” “怎么了?”我有些...
    開封第一講書人閱讀 169,787評論 0 365
  • 文/不壞的土叔 我叫張陵疮跑,是天一觀的道長组贺。 經(jīng)常有香客問我,道長祖娘,這世上最難降的妖魔是什么失尖? 我笑而不...
    開封第一講書人閱讀 60,237評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮渐苏,結(jié)果婚禮上掀潮,老公的妹妹穿的比我還像新娘。我一直安慰自己琼富,他們只是感情好仪吧,可當我...
    茶點故事閱讀 69,237評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鞠眉,像睡著了一般邑商。 火紅的嫁衣襯著肌膚如雪摄咆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,821評論 1 314
  • 那天人断,我揣著相機與錄音吭从,去河邊找鬼。 笑死恶迈,一個胖子當著我的面吹牛涩金,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播暇仲,決...
    沈念sama閱讀 41,236評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼步做,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了奈附?” 一聲冷哼從身側(cè)響起全度,我...
    開封第一講書人閱讀 40,196評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎斥滤,沒想到半個月后将鸵,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,716評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡佑颇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,794評論 3 343
  • 正文 我和宋清朗相戀三年顶掉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挑胸。...
    茶點故事閱讀 40,928評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡痒筒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出茬贵,到底是詐尸還是另有隱情簿透,我是刑警寧澤,帶...
    沈念sama閱讀 36,583評論 5 351
  • 正文 年R本政府宣布解藻,位于F島的核電站老充,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏舆逃。R本人自食惡果不足惜蚂维,卻給世界環(huán)境...
    茶點故事閱讀 42,264評論 3 336
  • 文/蒙蒙 一戳粒、第九天 我趴在偏房一處隱蔽的房頂上張望路狮。 院中可真熱鬧,春花似錦蔚约、人聲如沸奄妨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,755評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽砸抛。三九已至评雌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間直焙,已是汗流浹背景东。 一陣腳步聲響...
    開封第一講書人閱讀 33,869評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留奔誓,地道東北人斤吐。 一個月前我還...
    沈念sama閱讀 49,378評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像厨喂,于是被迫代替她去往敵國和親和措。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,937評論 2 361

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

  • 轉(zhuǎn)載自:block沒那么難(一):block的實現(xiàn)block沒那么難(二):block和變量的內(nèi)存管理block沒...
    路漫漫其修遠兮Wzt閱讀 323評論 0 0
  • iOS開發(fā)---Block詳解 Block的基礎(chǔ) 什么是Blocks蜕煌? 用一句話來描述:帶有自動變量的匿名函數(shù)(是...
    祀夢_閱讀 1,004評論 0 6
  • Block使用場景派阱,可以在兩個界面的傳值,也可以對代碼封裝作為參數(shù)的傳遞等斜纪。用過GCD就知道Block的精妙之處贫母。...
    Coder_JMicheal閱讀 725評論 2 1
  • Block 梳理與疑問 時隔一年,再次讀 《Objective-C 高級編程》傀广,看到 block 一章颁独,這一次從頭...
    DeerRun閱讀 645評論 0 2
  • 夜鶯2517閱讀 127,728評論 1 9