2018-10-10 weak strong block assign copy __weak __block

首先ARC之前屬性構(gòu)造器的關(guān)鍵字是retain,copy,assign,strong和weak是ARC之后引入的關(guān)鍵字。最新寫法一般也不推薦使用 retain了。

首先retain和strong幾乎等同

聲明屬性時(shí)用strong或者retain效果是一樣的。
retain和strong的區(qū)別在于修飾block的區(qū)別。我們都知道block應(yīng)該使用copy進(jìn)行修飾。先說結(jié)果:

  在MRC(Manual Reference Counting)下

  修飾block時(shí),strong相當(dāng)于copy。arc下

  修飾block時(shí),retain相當(dāng)于assign。(棧block引用計(jì)數(shù)增加了,但是棧block捕獲的變量沒有增加也沒有copy復(fù)制到堆上還是在原來的棧區(qū)已經(jīng)被釋放了,成野指針了 ,block還有block捕獲的局部變量沒了)

  導(dǎo)致結(jié)果:如果用strong修飾沒有問題,如果用retain修飾會(huì)崩潰。報(bào)野指針錯(cuò)誤。

詳解:

在MRC下,block的存儲(chǔ)分為三塊:堆區(qū),棧區(qū),全局區(qū)。在ARC下,block的存儲(chǔ)分為兩塊:全局區(qū),堆區(qū)。

如果在MRC下,我們用全局變量對(duì)棧區(qū)的block進(jìn)行了引用,然后修飾符還是使用的retain或者assign,那么結(jié)果就是后邊使用可能出現(xiàn)野指針訪問壞內(nèi)存。

結(jié)論就是block使用strong或者copy進(jìn)行修飾最安全。
作者:frankisbaby
鏈接:http://www.itdecent.cn/p/e2ccf2ae2b98
來源:簡書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

weak和assign

都可以打破循環(huán)引用
weak只能用來修飾對(duì)象 安全的把指針指向nil
assign既可以是對(duì)象也可以是基本類型  指向?qū)€可能不安全(已釋放或者已更改)

copy和strong copy和retain

參見 http://www.itdecent.cn/p/88b012f2c803
實(shí)際應(yīng)用中在修飾不可變對(duì)象 array等時(shí)沒區(qū)別  可變對(duì)象會(huì)出問題
因?yàn)樽址?@"aaa"的特殊性 視為字面量常量性能等問題 所以一般用copy來修飾
但是NSMutableString 要用strong 用copy會(huì)深拷貝成不可變字符串

__weak和__block

1.__block不管是ARC還是MRC模式下都可以使用,可以修飾對(duì)象,還可以修飾基本數(shù)據(jù)類型。
2.__weak只能在ARC模式下使用,也只能修飾對(duì)象(NSString),不能修飾基本數(shù)據(jù)類型(int)。
3.__block對(duì)象可以在block中被重新賦值,__weak不可以。
4.__block對(duì)象在ARC下可能會(huì)導(dǎo)致循環(huán)引用,非ARC下會(huì)避免循環(huán)引用,__weak只在ARC下使用,可以避免循環(huán)引用。

1:weak
很少有人知道weak表其實(shí)是一個(gè)hash(哈希)表,Key是所指對(duì)象的地址,Value是weak指針的地址數(shù)組。更多人的人只是知道weak是弱引用,所引用對(duì)象的計(jì)數(shù)器不會(huì)加一,并在引用對(duì)象被釋放的時(shí)候自動(dòng)被設(shè)置為nil。通常用于解決循環(huán)引用問題。但現(xiàn)在單知道這些已經(jīng)不足以應(yīng)對(duì)面試了,好多公司會(huì)問weak的原理。weak的原理是什么呢?下面就分析一下weak的工作原理(只是自己對(duì)這個(gè)問題好奇,學(xué)習(xí)過程中的筆記,希望對(duì)讀者也有所幫助)。

weak 實(shí)現(xiàn)原理的概括

Runtime維護(hù)了一個(gè)weak表,用于存儲(chǔ)指向某個(gè)對(duì)象的所有weak指針。weak表其實(shí)是一個(gè)hash(哈希)表,Key是所指對(duì)象的地址,Value是weak指針的地址(這個(gè)地址的值是所指對(duì)象的地址)數(shù)組。

weak 的實(shí)現(xiàn)原理可以概括一下三步:

1、初始化時(shí):runtime會(huì)調(diào)用objc_initWeak函數(shù),初始化一個(gè)新的weak指針指向?qū)ο蟮牡刂贰?/p>

2、添加引用時(shí):objc_initWeak函數(shù)會(huì)調(diào)用 objc_storeWeak() 函數(shù), objc_storeWeak() 的作用是更新指針指向,創(chuàng)建對(duì)應(yīng)的弱引用表。

3、釋放時(shí),調(diào)用clearDeallocating函數(shù)。clearDeallocating函數(shù)首先根據(jù)對(duì)象地址獲取所有weak指針地址的數(shù)組,然后遍歷這個(gè)數(shù)組把其中的數(shù)據(jù)設(shè)為nil,最后把這個(gè)entry從weak表中刪除,最后清理對(duì)象的記錄。

3:strong
默認(rèn)用strong進(jìn)行修飾 本質(zhì)是引用計(jì)數(shù)+1 維護(hù)的該變量的引用計(jì)數(shù)哈希表
//Assigning retained object to weak variable; object will be released after assignment
__weak UIlabel * _weakLabel = [[UILabel alloc] initWithFrame:CGRectMake(30, 170, 200, 60)];
_weakLabel.backgroundColor = [UIColor cyanColor];
_weakLabel.text = @"我是weak";
_weakLabel.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:_weakLabel];
初始化后對(duì)象因?yàn)槭侨跻靡糜?jì)數(shù)不增加 對(duì)象釋放 __weak指向nil;

UILabel *l1 = [[UILabel alloc] initWithFrame:CGRectMake(30, 170, 200, 60)];
__weak UILabel * _weakLabel = l1;
_weakLabel.backgroundColor = [UIColor cyanColor];
_weakLabel.text = @"我是weak";
_weakLabel.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:_weakLabel];

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容