《Objective-C 高級(jí)編程》干貨(2)-Blocks存儲(chǔ)域

上節(jié)講到了Block的實(shí)質(zhì) 挖滤,Blcok轉(zhuǎn)換為Block的結(jié)構(gòu)體類型的自動(dòng)變量页徐,_ block 變量轉(zhuǎn)換為 _block變量的結(jié)構(gòu)體類型的自動(dòng)變量解取。所謂結(jié)構(gòu)體類型的自動(dòng)變量,即棧上生成的該結(jié)構(gòu)體的實(shí)例挺尾。

Block與_ _block變量的實(shí)質(zhì).png

另外Block也可看作OC的對(duì)象鹅搪。該Block的類_NSConcreteStackBlock,也有很多其他類似的類
_NSConcreteStackBlock
_NSConcreteGlobalBlock
_NSConcreteMallocBlock
通過(guò)名字可以看到Block的存儲(chǔ)域

Block的存儲(chǔ)域

棧區(qū)
堆區(qū)
數(shù)據(jù)存儲(chǔ)區(qū)域(全局區(qū) )
具體如下圖


block存儲(chǔ)域.png

下面具體分析下三種類型Block

_NSConcreteGlobalBlock

在記述全局變量的地方使用的Block遭铺,生成的Block為_(kāi)NSConcreteGlobalBlock參數(shù)丽柿。例如

void (^blk)(void) = ^{printf("Global Block\n");};

int main(int argc, const char * argv[]) {
    @autoreleasepool {
      
        blk();

    }
    
    return 0;
}

C++

struct __blk_block_impl_0 {
  struct __block_impl impl;
  struct __blk_block_desc_0* Desc;
  __blk_block_impl_0(void *fp, struct __blk_block_desc_0 *desc, int flags=0) {
    impl.isa = &_NSConcreteGlobalBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};
static void __blk_block_func_0(struct __blk_block_impl_0 *__cself) {
printf("Global Block\n");}

static struct __blk_block_desc_0 {
  size_t reserved;
  size_t Block_size;
} __blk_block_desc_0_DATA = { 0, sizeof(struct __blk_block_impl_0)};
static __blk_block_impl_0 __global_blk_block_impl_0((void *)__blk_block_func_0, &__blk_block_desc_0_DATA);
void (*blk)(void) = ((void (*)())&__global_blk_block_impl_0);

int main(int argc, const char * argv[]) {
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 

        ((void (*)(__block_impl *))((__block_impl *)blk)->FuncPtr)((__block_impl *)blk);

    }

    return 0;
}

我們可以看到Block用結(jié)構(gòu)體的成員變量isa的初始化如下:

 impl.isa = &_NSConcreteGlobalBlock;

Block為_(kāi)NSConcreteGlobalBlock類對(duì)象具體總結(jié)如下:
1.記述全局變量的地方有Block語(yǔ)法時(shí)
2.Block語(yǔ)法的表達(dá)式中不使用應(yīng)截獲的自動(dòng)變量時(shí)
除此之外Blcok語(yǔ)法生成的Block為_(kāi)NSConcreteStackBlock。且設(shè)置在棧上魂挂。那_NSConcreteMallocBlock何時(shí)使用呢航厚?

配置在全局變量的Blcok,從變量作用域外也可以通過(guò)使用指針安全 的訪問(wèn)锰蓬。但設(shè)置在棧上的Blcok,如果其所屬的變量作用域結(jié)束眯漩,該Block就廢棄了芹扭。由于_ block變量也配置在棧上,同樣地赦抖,如果所屬的變量的作用域結(jié)束舱卡,則該 _blcok變量也會(huì)被廢棄。

Blcoks提供了將Block和_ _ block變量從棧上復(fù)制到堆上的方法來(lái)解決這個(gè)問(wèn)題队萤。如圖


從淺復(fù)制到堆上的Block與_ _blcok變量.png

復(fù)制到堆上的block將_NSConcreteMallocBlock對(duì)象寫入block的實(shí)體店變量

 impl.isa = &_NSConcreteMallocBlock

對(duì)于已經(jīng)在堆上的Blcok以及程序數(shù)據(jù)區(qū)上的Blcok轮锥,調(diào)用copy會(huì)如何呢?


image.png

Block淺復(fù)制到堆上時(shí)對(duì)_ _block的影響

Block淺復(fù)制到堆上時(shí)對(duì)_ _block的影響.png
  1. 1個(gè)Block中使用 _ block變量要尔,當(dāng)Block從棧淺復(fù)制到堆上時(shí)舍杜,使用的所有 block也必定從棧上復(fù)制到堆上,此時(shí)Blcok持有 block變量赵辕。復(fù)制Blcok也對(duì)所使用的 _block 變量沒(méi)什么影響既绩。
  2. 在多個(gè)Block中實(shí)用化 _ block變量時(shí),在任何一個(gè)Blcok復(fù)制到堆上時(shí)还惠, block也必定從棧上復(fù)制到堆上并被該Blcok所持有饲握,當(dāng)剩下的Blcok從棧復(fù)制到堆上時(shí),被復(fù)制的Block持有 block蚕键,并增加 _block的引用計(jì)數(shù)救欧。*

什么時(shí)候棧上的Blcok會(huì)復(fù)制到堆呢

1.調(diào)用Block的copy實(shí)例方法
2.Blcok作為函數(shù)返回值返回時(shí)
3.將Block賦值給附有 _ _strong修飾符id類型的類或Blcok類型成員變量時(shí)
4.在方法名中含有usingBlock的Cocoa框架方法或Grand Central Dispatch的API中傳遞Block時(shí)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市锣光,隨后出現(xiàn)的幾起案子笆怠,更是在濱河造成了極大的恐慌,老刑警劉巖誊爹,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件骑疆,死亡現(xiàn)場(chǎng)離奇詭異田篇,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)箍铭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門泊柬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人诈火,你說(shuō)我怎么就攤上這事兽赁”溉迹” “怎么了霉涨?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)棚饵。 經(jīng)常有香客問(wèn)我拍摇,道長(zhǎng)亮钦,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任充活,我火速辦了婚禮蜂莉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘混卵。我一直安慰自己映穗,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布幕随。 她就那樣靜靜地躺著蚁滋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪赘淮。 梳的紋絲不亂的頭發(fā)上辕录,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音梢卸,去河邊找鬼踏拜。 笑死,一個(gè)胖子當(dāng)著我的面吹牛低剔,可吹牛的內(nèi)容都是我干的速梗。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼襟齿,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼姻锁!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起猜欺,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤位隶,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后开皿,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體涧黄,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡篮昧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了笋妥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片懊昨。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖春宣,靈堂內(nèi)的尸體忽然破棺而出酵颁,到底是詐尸還是另有隱情,我是刑警寧澤月帝,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布躏惋,位于F島的核電站,受9級(jí)特大地震影響嚷辅,放射性物質(zhì)發(fā)生泄漏簿姨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一簸搞、第九天 我趴在偏房一處隱蔽的房頂上張望扁位。 院中可真熱鬧,春花似錦攘乒、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至闰集,卻和暖如春沽讹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背武鲁。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工爽雄, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沐鼠。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓挚瘟,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親饲梭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子乘盖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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