iOS Block在內(nèi)存中的位置及內(nèi)存管理

一胖缤、關(guān)于block在內(nèi)存的位置

Block在內(nèi)存中的位置分三種:
1、NSGlobalBlock:類似函數(shù),位于代碼段(未引用外部變量):

float (^sum)(float, float) = ^(float a, float b){



    return a + b;

};

2督怜、NSStackBlock:位于棧內(nèi)存丘跌,函數(shù)返回后block將無效(引用外部變量袭景,但只能在該函數(shù)作用域內(nèi)使用,出作用域該變量內(nèi)存已被釋放闭树,出作用域觸發(fā)block訪問該變量會(huì)Crash):

{

NSArray *testArr = @[@"1", @"2"];



void (^TestBlock)(void) = ^{



    NSLog(@"testArr :%@", testArr);

};



NSLog(@"block is %@", ^{



    NSLog(@"test Arr :%@", testArr);

});
}

3耸棒、NSMallocBlock:位于堆內(nèi)存(對NSStackBlock 使用copy修飾(strong 應(yīng)該也可以))該類型擁有保存外部變量內(nèi)存的能力。所以調(diào)用外部變量不會(huì)crash,下面將講解對外部變量的存取管理蔼啦。

二榆纽、關(guān)于block外部變量的存取管理

#######在這里只討論ARC機(jī)制下

- (void)test

{
int a = 0;
__block int  b = 0;
self.globstring = @"1";
NSString *__localString = @"1";
__block NSString *_blockString = @"1";
printf("a address: %p\n", &a); //a address: 0x7fff56516b3c

printf("b address: %p\n", &b); //b address: 0x7fff56516b30

printf("local address: %p\n", &__localString); //local address: 0x7fff56516b00
printf("_block address: %p\n", &_blockString); //_block address: 0x7fff56516af8
printf("glob address: %p\n", &_globstring); //glob address: 0x7fed5bc09520

void (^TestBlock)(void) = ^{
    printf("a value: %d\n", a); //a value: 0
    printf("b value: %d\n", b); //b value: 1
    printf("b address: %p\n", &b); //b address: 0x60800002a7f8
    
    printf("local address: %p\n", &__localString); //       local address: 0x6080000979a0
    NSLog(@"lockstring is : %@\n", __localString); //lockstring is : 1
    
    printf("_blcok address: %p\n", &_blockString); //_blcok address: 0x6080000470d8
    NSLog(@"_blcokstring is : %@\n", _blockString); //_blcokstring is : 2

    printf("globaddress: %p\n", &_globstring); //globaddress: 0x7fed5bc09520
    NSLog(@"globstring is : %@\n", _globstring); //globstring is : 2
    
};
 __weak typeof(self) this = self;
self.copyBlock = ^{
    printf("a value: %d\n", a); //a value: 0
    printf("b value: %d\n", b); // b value: 1
    printf("b address: %p\n", &b); // b address: 0x60800002a7f8
    printf("copy block local address: %p\n", &__localString); //copy block local address: 0x608000099660
    
    NSLog(@"copy block string is : %@\n", __localString); //copy block string is : 1
    
    printf("_blcok address: %p\n", &_blockString); //_blcok address: 0x6080000470d8
    
    NSLog(@"_blcokstring is : %@\n", _blockString); //_blcokstring is : 2
    
    printf("glob address: %p\n", &_globstring); //glob address: 0x7fed5bc09520
    
    NSLog(@"string is : %@\n", this.globstring); //string is : 2

};
a = 1;
b = 1;
printf("a address: %p\n", &a); //local address: 0x7fff56516b3c
printf("b address: %p\n", &b); //_block address: 0x60800002a7f8

printf("local address: %p\n", &__localString); //local address:  0x7fff56516b00
printf("_block address: %p\n", &_blockString); //_block address: 0x60800002a7f8

__localString = nil;
_blockString = @"2";
self.globstring = @"2";

TestBlock();
self.copyBlock();
}

通過觀察上面的輸出,得出結(jié)論 :
1捏肢、普通的局部變量奈籽,BLOCK聲明時(shí)會(huì)COPY它的值,并且擁有新的地址鸵赫,也就是說block內(nèi)部a 地址和外部a地址不同(如上)衣屏。互不影響辩棒。
2狼忱、__block局部變量,BLOCK聲明時(shí)會(huì)在堆中新建一個(gè)內(nèi)存地址一睁,并且BLOCK之后的所有b 或者 _blockString (如上)都是這個(gè)地址钻弄,所以后續(xù)的讀寫都是再這個(gè)地址上進(jìn)行。會(huì)不想影響者吁。即使不觸發(fā)block 地址也已經(jīng)不是原來的地址窘俺。
3、全局變量 globstring (如上)BLOCK 訪問都是 它本身的地址复凳。直接讀寫操作瘤泪。
4灶泵、BLOCK引用外部對象時(shí)會(huì)強(qiáng)引用外部變量 ,如果該外部變量也強(qiáng)引用BLOCK就會(huì)造成return circle (比如self property block ,block 內(nèi)部訪問self 或者self的屬性)对途,為了解決這個(gè)使用weakSelf赦邻。

以上均為測試并發(fā)表的自己的見解,只能模糊的用自己的語言描述实檀。對于內(nèi)存管理一直都是一知半解惶洲。網(wǎng)上看的BLOCK的結(jié)構(gòu)看的不是很懂。只能通過實(shí)驗(yàn)的方式看地址的變化劲妙。希望大家有見解都寫在評論里 幫助我加深理解湃鹊,比如有文章說是__block 變量地址在BLOCK申明后地址是怎么發(fā)生改變的?希望大家多多關(guān)照镣奋。共同進(jìn)步币呵!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市侨颈,隨后出現(xiàn)的幾起案子余赢,更是在濱河造成了極大的恐慌,老刑警劉巖哈垢,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妻柒,死亡現(xiàn)場離奇詭異,居然都是意外死亡耘分,警方通過查閱死者的電腦和手機(jī)举塔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來求泰,“玉大人央渣,你說我怎么就攤上這事】势担” “怎么了芽丹?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長卜朗。 經(jīng)常有香客問我拔第,道長,這世上最難降的妖魔是什么场钉? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任蚊俺,我火速辦了婚禮,結(jié)果婚禮上逛万,老公的妹妹穿的比我還像新娘泳猬。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布暂殖。 她就那樣靜靜地躺著,像睡著了一般当纱。 火紅的嫁衣襯著肌膚如雪呛每。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天坡氯,我揣著相機(jī)與錄音晨横,去河邊找鬼。 笑死箫柳,一個(gè)胖子當(dāng)著我的面吹牛手形,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播悯恍,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼库糠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了涮毫?” 一聲冷哼從身側(cè)響起瞬欧,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎罢防,沒想到半個(gè)月后艘虎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡咒吐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年野建,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恬叹。...
    茶點(diǎn)故事閱讀 38,724評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡候生,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出妄呕,到底是詐尸還是另有隱情陶舞,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布绪励,位于F島的核電站肿孵,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏疏魏。R本人自食惡果不足惜停做,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望大莫。 院中可真熱鬧蛉腌,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至河咽,卻和暖如春钠右,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背忘蟹。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工飒房, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人媚值。 一個(gè)月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓狠毯,卻偏偏與公主長得像,于是被迫代替她去往敵國和親褥芒。 傳聞我的和親對象是個(gè)殘疾皇子嚼松,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評論 2 350

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