__block和__weak的區(qū)別

一、__block

優(yōu)點(diǎn):

  • 擴(kuò)大變量的作用域苏研。</br>
  • 控制對象的生命周期,防止循環(huán)引用摹蘑。
  • 是強(qiáng)引用,在非ARC環(huán)境下可以使用 __block替代__weak</br>

<pre>
int a = 0;
self.theBlock = ^(){
a = 2;
};
報錯衅鹿,a的值不能被修改撒踪,因?yàn)檫@里只是簡單的值傳遞。
__block int a = 0;
self.theBlock = ^(){
a = 2;
};
編譯通過大渤,指針傳遞制妄。


下面來看看block的作用域,block有以下三種:
1._NSConcreteStackBlock 保存在棧中的block泵三,出棧時會被銷毀
2._NSConcreteGlobalBlock 全局的靜態(tài)block耕捞,不會訪問任何外部變量
3._NSConcreteMallocBlock 保存在堆中的block衔掸,當(dāng)引用計(jì)數(shù)為0時會被銷毀
一般我們接觸到得是在棧上生成的block。當(dāng)我們把Block作為全局變量使用時:
void (^block)(void) = ^{NSLog(@"This is a Global Block");};

int main(int argc, const char * argv[]) {
@autoreleasepool {
block();
}
return 0;
}
分配在全局變量上的Block,在變量作用域外也可以通過指針安全的訪問俺抽。</br>但分配在棧上的Block敞映,如果它所屬的變量作用域結(jié)束,該Block就被廢棄磷斧。
同樣地, __block變量也分配在棧上振愿,當(dāng)超過該變量的作用域時,該__block變量也會被廢棄瞳抓。


循環(huán)引用:我們可以使用下述代碼解除Block循環(huán)引用的問題
__block id tmp = self;
void(^block)(void) = ^{
tmp = nil;
};
block();
通過執(zhí)行block方法埃疫,nil被賦值到__block變量tmp中。這個時候__block變量對 self
的強(qiáng)引用失效孩哑,從而避免循環(huán)引用的問題栓霜。缺點(diǎn)是執(zhí)行block才能解除循環(huán)引用横蜒。
</pre>

我們一般可以使用copy方法手動將 Block 或者 block變量從棧復(fù)制到堆上胳蛮。
比如我們把Block做為類的屬性訪問時,我們一般把該屬性設(shè)為copy丛晌。

在MRC環(huán)境下仅炊,__block是弱引用,在ARC環(huán)境下是強(qiáng)引用澎蛛,親測抚垄,很奇怪

二、__weak

優(yōu)點(diǎn):

  • 弱引用谋逻,防止循環(huán)引用
.h
@property (nonatomic, strong) People \*myPeople;
@property (nonatomic, strong) void(^theBlock)();
.m
    self.theBlock = ^(){
        self.myPeople.name = @"ddd";
    };

當(dāng)出棧呆馁,之后controller的dealloc()方法未被調(diào)用
作如下修改

self.theBlock = ^(){
        weakSelf.myPeople.name = @"ddd";
    };

dealloc()被調(diào)用,在MRC環(huán)境下用retainCount方法也能看到引用計(jì)數(shù)的變化
總結(jié):
__weak本身可以防止循環(huán)引用毁兆,但是當(dāng)block外部的變量釋放之后浙滤,里面也會出現(xiàn)訪問不到對象的問題,這時候气堕,在block里面用__strong來修飾weakObj纺腊,就可以使外部對象既能保持住,又能防止循環(huán)引用茎芭。
參考文檔
__weak與__block區(qū)別
黑幕背后的__block修飾符
Objective-C中的Block

@3樓
start()方法結(jié)束后2秒揖膜,打印shop的string屬性,如下
**
2017-03-25 18:11:01.749 TestWeak[57495:1819695] shop --0x7fff507bbb58
2017-03-25 18:11:01.750 TestWeak[57495:1819695] weakShop --0x7fff507bbb50
2017-03-25 18:11:03.750 TestWeak[57495:1819695] (null)
**
shop已經(jīng)被釋放梅桩,string屬性沒能成功打印

- (void)viewDidLoad {
    [super viewDidLoad];
    [self start];
}

-(void)start{
    RBShop *shop = [[RBShop alloc] init];
    shop.string = @"welcome";
    __weak typeof(shop) weakShop = shop;
    shop.myBlock = ^(){
        
//        RBShop *strongshop = weakShop;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"%@",weakShop.string);
//            NSLog(@"strongshop -- %p",&strongshop);
        });
        
    };
    shop.myBlock();
    NSLog(@"shop --%p",&shop);
    NSLog(@"weakShop --%p",&weakShop);

}```
將注釋打開

-(void)start{
RBShop *shop = [[RBShop alloc] init];
shop.string = @"welcome";
__weak typeof(shop) weakShop = shop;
shop.myBlock = ^(){

    RBShop *strongshop = weakShop;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"%@",strongshop.string);
        NSLog(@"strongshop -- %p",&strongshop);
    });
    
};
shop.myBlock();
NSLog(@"shop --%p",&shop);
NSLog(@"weakShop --%p",&weakShop);

}

打印如下
**
2017-03-25 18:12:26.753 TestWeak[57516:1821278] shop --0x7fff5d856b58
2017-03-25 18:12:26.754 TestWeak[57516:1821278] weakShop --0x7fff5d856b50
2017-03-25 18:12:28.946 TestWeak[57516:1821278] welcome
2017-03-25 18:12:28.947 TestWeak[57516:1821278] strongshop -- 0x608000248f60
**
最后數(shù)據(jù)打印了出來次氨,shop也釋放了

針對**在block里面用__strong來修飾weakObj,就可以使外部對象既能保持住摘投,又能防止循環(huán)引用**這句話:
>在block里面再對weakshop進(jìn)行一次強(qiáng)引用煮寡,這里的生成的strongshop,不會干擾外部的對象犀呼,當(dāng)cgd內(nèi)部的block執(zhí)行結(jié)束就會釋放掉shop







最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末幸撕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子外臂,更是在濱河造成了極大的恐慌坐儿,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宋光,死亡現(xiàn)場離奇詭異貌矿,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)罪佳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進(jìn)店門逛漫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赘艳,你說我怎么就攤上這事酌毡。” “怎么了蕾管?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵枷踏,是天一觀的道長。 經(jīng)常有香客問我掰曾,道長旭蠕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任旷坦,我火速辦了婚禮掏熬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘塞蹭。我一直安慰自己孽江,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布番电。 她就那樣靜靜地躺著岗屏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪漱办。 梳的紋絲不亂的頭發(fā)上这刷,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天,我揣著相機(jī)與錄音娩井,去河邊找鬼暇屋。 笑死,一個胖子當(dāng)著我的面吹牛洞辣,可吹牛的內(nèi)容都是我干的咐刨。 我是一名探鬼主播昙衅,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼定鸟!你這毒婦竟也來了而涉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤联予,失蹤者是張志新(化名)和其女友劉穎啼县,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沸久,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡季眷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了卷胯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片子刮。...
    茶點(diǎn)故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖诵竭,靈堂內(nèi)的尸體忽然破棺而出话告,到底是詐尸還是另有隱情,我是刑警寧澤卵慰,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布沙郭,位于F島的核電站,受9級特大地震影響裳朋,放射性物質(zhì)發(fā)生泄漏病线。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一鲤嫡、第九天 我趴在偏房一處隱蔽的房頂上張望送挑。 院中可真熱鬧,春花似錦暖眼、人聲如沸惕耕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽司澎。三九已至,卻和暖如春栋豫,著一層夾襖步出監(jiān)牢的瞬間挤安,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工丧鸯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蛤铜,地道東北人。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像围肥,于是被迫代替她去往敵國和親剿干。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評論 2 355

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

  • 1.__block不管是ARC還是MRC模式下都可以使用虐先,可以修飾對象怨愤,還可以修飾基本數(shù)據(jù)類型。 2.__weak...
    城市之光閱讀 479評論 0 0
  • //聯(lián)系人:石虎QQ: 1224614774昵稱:嗡嘛呢叭咪哄 API Reference對__block變量修飾...
    石虎132閱讀 2,082評論 0 11
  • 1.__block不管是ARC還是MRC模式下都可以使用蛹批,可以修飾對象,還可以修飾基本數(shù)據(jù)類型篮愉。 2.__weak...
    世玉茹花閱讀 383評論 0 0
  • __block和__weak的區(qū)別 __block 在ARC和MRC下都可以使用腐芍,既可以修飾對象,也可以修飾基本數(shù)...
    奕十八閱讀 275評論 0 0
  • 有些事情有些人經(jīng)歷過就好试躏,懷念的也許只是當(dāng)時的那份感覺猪勇,很美好啊,哈哈颠蕴,我們都會更好的泣刹。
    傲嬌靜Q閱讀 134評論 0 0