引用別人十個字對棧和堆的總結(jié)
棧是吃了吐 堆是吃了拉
下面進入主題為什么要用copy去修飾block呢
個人理解:默認情況下,block會存檔在棧中(棧是吃了吐)褂萧,所以block會在函數(shù)調(diào)用結(jié)束被銷毀,在調(diào)用會報空指針異常祟蚀,如果用copy修飾的話咏花,可以使其保存在堆區(qū)(堆是吃了拉) 矗蕊,它的生命周期會隨著對象的銷毀而結(jié)束的。只要對象不銷毀杠河,我們就可以調(diào)用在堆中的block碌尔。
在了解block為什么要用copy之前浇辜,我們要先了解block的三種類型
一 NSGlobalBlock:全局的靜態(tài)block 沒有訪問外部變量 你的block類型就是這種類型(也就是說你的block沒有調(diào)用其他外部變量)
二 NSStackBlock:保存在棧中的block,沒有用copy去修飾并且訪問了外部變量唾戚,你的block類型就是這種類型柳洋,會在函數(shù)調(diào)用結(jié)束被銷毀 (需要在MRC)
三 NSMallocBlock 保存在堆中的block 此類型blcok是用copy修飾出來的block 它會隨著對象的銷毀而銷毀,只要對象不銷毀叹坦,我們就可以調(diào)用的到在堆中的block熊镣。
下面代碼演示
第一種全局的block 這種block不訪問外部的變量,我們在開發(fā)中block都會訪問外部的變量募书,所以這種block開發(fā)不會用到绪囱,作為一個了解
void(^testOneBlock)() = ^(){
NSLog(@"我是全局的block");
};
NSLog(@"testOneBlock=%@",testOneBlock);
//控制臺輸出
2017-06-10 09:45:09.767 ReactiveCocoa[871:14517]
testOneBlock=<__NSGlobalBlock__: 0x1045982d0>//全局block 他會隨程序銷毀而銷毀
第二種棧區(qū)block 這種block訪問外部變量,我們重點了解的是第二種和第三種莹捡,但是必須要在MRC的模式下控制臺才會輸出NSStackBlock類型
如何把當前類改為MRC:Build phases -> Compile Sources -> 雙擊當前類會彈出輸入框 -> 把-fno-objc-arc
復(fù)制粘貼進去 -> OK
//需要MRC模式
int a = 5;
void(^testTwoBlock)() = ^(){
NSLog(@"%d",a);
};
NSLog(@"testTwoBlock=%@",testTwoBlock);
//控制臺輸出
2017-06-10 09:45:09.768 ReactiveCocoa[871:14517]
testTwoBlock= <__NSStackBlock__: 0x7fff5b668770>//棧區(qū)block 函數(shù)調(diào)用完畢就會銷毀
[testTwoBlock copy] 這樣操作就會變成堆區(qū)block
第三種堆區(qū)block 這種block是用copy去修飾的 它的生命周期會隨對象銷毀而銷毀
int a = 5;
self.block1 = ^(NSString *str, UIColor *color){
NSLog(@"%d",a);
};
NSLog(@"block1=%@",self.block1);
//控制臺輸出
2017-06-10 10:02:35.107 ReactiveCocoa[1075:19674] block1=<__NSMallocBlock__: 0x60000004ee50>//用copy修飾的不會函數(shù)調(diào)用完就結(jié)束鬼吵,隨對象銷毀才銷毀 這種是在開發(fā)中正確使用block的姿勢
第三種block在有些情況下會造成block的循環(huán)引用,我會寫在下一篇文章中
寫簡書只是當作筆記來寫篮赢,如果那里使用的姿勢不正確呢齿椅,歡迎大神來教導(dǎo)正確姿勢
(我是一個小菜逼,沒事就是愛裝逼)沒有特別的意思 純屬覺得順口启泣。辛苦啦都看完啦