翻新
__block和__weak的認(rèn)識(shí)(iOS)
果然還是對(duì)最基礎(chǔ)的知識(shí)了解不透徹缰儿,今天看一看iOS中的兩個(gè)修飾符:__block
和 __weak
。也是做一下溫習(xí)吧忧换。
1、先說(shuō)weak,<弱引用>
我們知道weak的使用热康,比如聲明一個(gè)控件屬性,就會(huì)用到weak劣领。
看代碼:
@property(nonatomic,weak)UILabel *label;
當(dāng)然這并不是說(shuō)聲明控件就一定使用weak
姐军,相反的我在手動(dòng)創(chuàng)建控件是大多數(shù)會(huì)使用strong
。但如果你比較細(xì)心的話,你會(huì)發(fā)現(xiàn)我們使用xib
時(shí)奕锌,使用的卻是weak
這一屬性著觉。那問(wèn)題來(lái)了,我們使用strong
和 weak
的時(shí)機(jī)是何時(shí)呢惊暴?咱們接著往下看饼丘。
從storyboard
或者xib
上創(chuàng)建控件
在控件放在view上的時(shí)候,已經(jīng)形成了如下的引用關(guān)系,以 UILabel
為例:UIViewController->UIView->subView-> UILabel
辽话,然后你為這個(gè)UILabel
聲明一個(gè)weak
屬性
@property(nonatomic,weak) IBOOutlet UILabel * label;
相當(dāng)于xib
對(duì)這個(gè)label
是強(qiáng)引用肄鸽,你聲明的屬性對(duì)它是弱引用。
手動(dòng)創(chuàng)建控件
- a). 將控件聲明成
strong
@property(nonatomic,strong) UIlabel * label;
那么你在實(shí)現(xiàn)這個(gè)控件時(shí)只需這樣:
_label = [[UIlabel alloc]init];
[self.view addSubview:_label]
- b). 將控件聲明成weak
@property(nonatomic,weak) UIlabel * label;
那么你在實(shí)現(xiàn)這個(gè)控件時(shí)需要這樣:
UIlabel *label = [[UIlabel alloc]init];
_label = label;
[self.view addSubview:_label];
關(guān)于block
循環(huán)引用的問(wèn)題
由于block
會(huì)復(fù)制外部的變量油啤,所以如果不注意典徘,就會(huì)造成循環(huán)引用。對(duì)于這種情況村砂,需要將引用的一方變成weak
烂斋,從而避免循環(huán)引用。
看代碼:
BlocksViewController *blockVC = [[BlocksViewController alloc]init];
__weak ViewController *weekSelf = self;
1础废、使用弱引用來(lái)解決block循環(huán)引用問(wèn)題
2汛骂、block能截取自動(dòng)變量,并且是不能在block塊中進(jìn)行修改的(除非用 __block修飾符)這里的 weekSelf.textField.text 的值是被修改了评腺,并且沒(méi)有使用 __block修飾符帘瞭。原因是因?yàn)閠extField是全局變量,如果定義一個(gè)局部變量蒿讥,比如:定義個(gè) “text”是不能被修改的蝶念,編譯器會(huì)報(bào)錯(cuò).
//block回調(diào)傳值
[blockVC returnValue:^(NSString *content) {
weekSelf.textField.text = content;
// text = content;//這里會(huì)提示錯(cuò)失__block;
}];
2、strong
和weak
的區(qū)別
strong
:強(qiáng)引用芋绸,也是我們通常說(shuō)的引用媒殉,其存亡直接決定了所指向?qū)ο蟮拇嫱觥H绻淮嬖谥赶蛞粋€(gè)對(duì)象的引用摔敛,并且此對(duì)象不再顯示在列表中廷蓉,則此對(duì)象會(huì)被從內(nèi)存中釋放。weak
:弱引用马昙,不決定對(duì)象的存亡桃犬。即使一個(gè)對(duì)象被持有無(wú)數(shù)個(gè)弱引用,只要沒(méi)有強(qiáng)引用指向它行楞,那么還是會(huì)被清除攒暇。strong
和copy
是用來(lái)修飾強(qiáng)引用的屬性,weak
用來(lái)修飾弱引用的屬性子房;strong
形用、weak
需要ARC
支持才能使用就轧,copy
不需要ARC
支持strong
與retain
功能相似;weak
與assign
相似尾序,只是當(dāng)對(duì)象消失后weak
會(huì)自動(dòng)把指針變?yōu)?code>nil;
3钓丰、關(guān)于__block
先看一段代碼:
@autoreleasepool {
__block NSInteger value = 0;
void (^block)(void) = ^{
value = 1;
};
block();
NSLog(@"val = %ld", value);
}
我們現(xiàn)在看著可能得不出什么結(jié)論,那么每币,我們?cè)倏聪旅娴拇a携丁,為了直觀,我以圖片的形式呈現(xiàn):
現(xiàn)在對(duì)比就明顯了兰怠。
下面總結(jié)一下:
a)__block
對(duì)象在block
中是可以被修改梦鉴、重新賦值的。
b)__block
對(duì)象在block
中不會(huì)被block
強(qiáng)引用一次揭保,從而不會(huì)出現(xiàn)循環(huán)引用問(wèn)題肥橙。
c)blocks
可以訪問(wèn)局部變量,但是不能修改秸侣。如果修改局部變量存筏,需要加__block
,所以__block
是讓修改外部變量的值.
對(duì)于 block
外的變量引用,block
默認(rèn)是將其復(fù)制到其數(shù)據(jù)結(jié)構(gòu)中來(lái)實(shí)現(xiàn)訪問(wèn)的
對(duì)于用 __block
修飾的外部變量引用味榛,block
是復(fù)制其引用地址來(lái)實(shí)現(xiàn)訪問(wèn)的
4椭坚、__block
和 __weak
修飾符的區(qū)別
1.__block
不管是ARC
還是MRC
模式下都可以使用,可以修飾對(duì)象搏色,還可以修飾基本數(shù)據(jù)類型善茎。
2.__weak
只能在ARC
模式下使用,也只能修飾對(duì)象(NSString)
频轿,不能修飾基本數(shù)據(jù)類型(int)
垂涯。
** 3. __block
對(duì)象可以在block
中被重新賦值,__weak
不可以航邢。**
鏈接: