(iOS) __block和__weak認識

來源:互聯網
上載者:User

標籤:

果然還是對最基礎的知識瞭解不透徹,今天看一看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認識

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.