標籤:
果然還是對最基礎的知識瞭解不透徹,今天看一看iOS中的兩個修飾符:__block和__weak 。也是做一下溫習吧。
1、先說weak,<弱引用>
我們知道weak的使用,比如聲明一個控制項屬性,就會用到weak。
看代碼:
@property(nonatomic,weak)UILabel *label;
當然這並不是說聲明控制項就一定使用weak,相反的我在手動建立控制項是大多數會使用strong。但如果你比較細心的話,你會發現我們使用xib時,使用的卻是weak這一屬性。那問題來了,我們使用strong 和 weak 的時機是何時呢?咱們接著往下看。
從storyboard 或者xib上建立控制項
在控制項放在view上的時候,已經形成了如下的參考關聯性,以UILabel為例:UIViewController->UIView->subView-> UILabel
然後你為這個UILabel聲明一個weak屬性
@property(nonatomic,weak) IBOOutlet UILabel * label;
相當於xib對這個label是強引用,你聲明的屬性對它是弱引用。
手動建立控制項 a). 將控制項聲明成strong
@property(nonatomic,strong) UIlabel * label;
那麼你在實現這個控制項時只需這樣:
_label = [[UIlabel alloc]init];[self.view addSubview:_label]
b). 將控制項聲明成weak
@property(nonatomic,weak) UIlabel * label;
那麼你在實現這個控制項時需要這樣:
UIlabel *label = [[UIlabel alloc]init];_label = label;[self.view addSubview:_btn];
關於block循環參考的問題
由於block會複製外部的變數,所以如果不注意,就會造成循環參考。對於這種情況,需要將引用的一方變成weak,從而避免循環參考。
看代碼:
BlocksViewController *blockVC = [[BlocksViewController alloc]init];__weak ViewController *weekSelf = self;/*** 1、使用弱引用來解決block循環參考問題** 2、block能截取自動變數,並且是不能在block塊中進行修改的(除非用 __block修飾符)這裡的 weekSelf.textField.text 的值是被修改了,並且沒有使用 __block修飾符。原因是因為textField是全域變數,如果定義一個局部變數,比如:定義個 “text”是不能被修改的,編譯器會報錯,*///block回調傳值[blockVC returnValue:^(NSString *content) {weekSelf.textField.text = content;// text = content;//這裡會提示錯失__block;}];
2、strong和weak的區別
a) strong:強引用,也是我們通常說的引用,其存亡直接決定了所指向對象的存亡。如果不存在指向一個對象的引用,並且此對象不再顯示在列表中,則此對象會被從記憶體中釋放。
b) weak:弱引用,不決定對象的存亡。即使一個對象被持有無數個弱引用,只要沒有強引用指向它,那麼還是會被清除。
c)strong和copy是用來修飾強引用的屬性,weak 用來修飾弱引用的屬性;
d)strong、weak 需要ARC支援才能使用,copy不需要ARC支援
e)strong與retain功能相似;weak與assign相似,只是當對象消失後weak會自動把指標變為nil;
3、關於__block
先看一段代碼:
@autoreleasepool {__block NSInteger value = 0;void (^block)(void) = ^{value = 1;};block();NSLog(@"val = %ld", value);}
我們現在看著可能得不出什麼結論,那麼,我們再看下面的代碼,為了直觀,我以圖片的形式呈現:
現在對比就明顯了。
下面總結一下:
a) 1.__block對象在block中是可以被修改、重新賦值的。
b)2.__block對象在block中不會被block強引用一次,從而不會出現循環參考問題。
c)3.blocks可以訪問局部變數,但是不能修改。
如果修改局部變數,需要加__block ,所以__block 是讓修改外部變數的值.
對於 block 外的變數引用,block 預設是將其複製到其資料結構中來實現訪問的
對於用 __block 修飾的外部變數引用,block 是複製其引用地址來實現訪問的
4、__block 和__weak修飾符的區別:
1>.__block不管是ARC還是MRC模式下都可以使用,可以修飾對象,還可以修飾基礎資料型別 (Elementary Data Type)。
2>.__weak只能在ARC模式下使用,也只能修飾對象(NSString),不能修飾基礎資料型別 (Elementary Data Type)(int)。
3>.__block對象可以在block中被重新賦值,__weak不可以。
**連結:**
[談Objective-C block的實現]<http://blog.devtang.com/2013/07/28/a-look-inside-blocks/>
[Blocks are Objective-C`s]<http://rypress.com/tutorials/objective-c/blocks>
[iOS開發-由淺至深學習block]<http://www.cnblogs.com/luoxiaofu/p/5445327.html>
(iOS) __block和__weak認識