(iOS) __block和__weak認識


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

我們現在看着可能得不出什么結論,那么,我們再看下面的代碼,為了直觀,我以圖片的形式呈現:

__block改變block內部變量問題一

 

__block改變block內部變量問題二

現在對比就明顯了。

下面總結一下:

a) 1.__block對象在block中是可以被修改、重新賦值的。


b)2.__block對象在block中不會被block強引用一次,從而不會出現循環引用問題。


c)3.blocks可以訪問局部變量,但是不能修改。


如果修改局部變量,需要加__block ,所以__block 是讓修改外部變量的值.

 

對於 block 外的變量引用,block 默認是將其復制到其數據結構中來實現訪問的

const-non-local-variables

對於用 __block 修飾的外部變量引用,block 是復制其引用地址來實現訪問的

mutable-non-local-variables

4、__block 和__weak修飾符的區別:

1>.__block不管是ARC還是MRC模式下都可以使用,可以修飾對象,還可以修飾基本數據類型。

2>.__weak只能在ARC模式下使用,也只能修飾對象(NSString),不能修飾基本數據類型(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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM