iOS:關(guān)于修飾符的那些事

關(guān)于iOS修飾符

首先強(qiáng)調(diào)一下:

強(qiáng)引用:當(dāng)前對象被其他對象引用時(shí),會(huì)執(zhí)行retain操作,引用計(jì)數(shù)器+1。當(dāng)retainCount=0時(shí),該對象才會(huì)被銷毀。因?yàn)槲覀円M(jìn)行對象的內(nèi)存管理,所以這是默認(rèn)的引用方式。(默認(rèn)是強(qiáng)引用)

弱引用:當(dāng)前對象的生命周期不被是否由其他對象引用限制,它本該什么時(shí)候銷毀就什么時(shí)候被銷毀。即使它的引用沒斷,但是當(dāng)它的生存周期到了時(shí)就會(huì)被銷毀。

所以一般來說,類“內(nèi)部”的屬性設(shè)置為strong,類“外部”的屬性設(shè)置為weak。說到底就是一個(gè)歸屬權(quán)的問題。小心出現(xiàn)循環(huán)引用導(dǎo)致內(nèi)存無法釋放。

1.NSNumber 是不可變的( immutable )?

使用 Copy 是沒有意義的,系統(tǒng)不會(huì)給它分配新的內(nèi)存空間,應(yīng)該使用Strong修飾

2.NSString用Copy還是Strong

給NSString屬性賦值,如果是不可變對象,Strong和Copy 引用計(jì)數(shù)都會(huì)+1

如果是可變對象,copy會(huì)深copy對象,Strong的引用計(jì)數(shù)+1,Copy的引用計(jì)數(shù)此時(shí)+2;

當(dāng)源字符串是NSString時(shí),由于字符串是不可變的,所以,不管是strong還是copy屬性的對象,都是指向源對象,copy操作只是做了次淺拷貝。

當(dāng)源字符串是NSMutableString時(shí),strong屬性只是增加了源字符串的引用計(jì)數(shù),而copy屬性則是對源字符串做了次深拷貝,產(chǎn)生一個(gè)新的對象,且copy屬性對象指向這個(gè)新的對象。

但是改屬性的類型始終都是NSString,而不是NSMutableString。
一般我們將對象聲明為NSString時(shí),都不希望它改變,所以大多數(shù)情況下,我們建議用copy。

3.用字面量語法給NSString賦值

使用字面量語法賦值了,類似于

????NSString*str1=@"1234567890";

這樣的方法創(chuàng)建的字符串,retainCount作為NSInterger打印為-1,其實(shí)最其值應(yīng)為4294967295,這意味著無限的“retainCount”,也就是說這個(gè)對象是不能被釋放的。

所以用這樣的方式創(chuàng)建字符串,無論創(chuàng)建多少次,他們都指向同一個(gè)對象(同樣的內(nèi)存地址)。

4.NSString被不同修飾符操作

對一個(gè)NSString進(jìn)行retain和copy操作,最終仍然是自己,引用計(jì)數(shù)+1;但是進(jìn)行MutableCopy會(huì)將其Copy到堆上,操作完成后引用計(jì)數(shù)為1。

5.weak和strong的區(qū)別

?兩者不同的是 當(dāng)一個(gè)對象不再有strong類型的指針指向它的時(shí)候 它會(huì)被釋放 ?,即使還有weak型指針指向它。

只要最后一個(gè)strong型指針不再指向?qū)ο?,那么對象就?huì)被釋放,同時(shí)所有的weak型指針都將會(huì)被清除。

6.assgin和weak的區(qū)別

weak表示了一種(non-relationship)非擁有關(guān)系,為這類型屬性賦值時(shí),set方法既不保留新值,也不會(huì)釋放舊值。

assign也可以用來修飾對象,但是使用assign修飾的對象在釋放后,指針還是存在的,也就是說指針沒有置為nil,會(huì)造成野指針。assign修飾的基本數(shù)據(jù)類型(例如NSInteger,CGFloat等)和C數(shù)據(jù)類型(int,float,double,char)等一般分配在??臻g上,??臻g的內(nèi)存會(huì)由系統(tǒng)自動(dòng)處理,當(dāng)分配的??臻g的內(nèi)存沒有被指針指向時(shí)就會(huì)被銷毀,所以不會(huì)造成野指針異常。

weak比assign多了一個(gè)功能就是在當(dāng)前屬性消失(引用計(jì)數(shù)為0)后,會(huì)自動(dòng)賦值為nil;這樣給weak修飾的屬性發(fā)消息就不會(huì)因?yàn)橐爸羔樤斐蒫rash。

此外,還有一個(gè)修飾符unsafe_unretained,這個(gè)修飾符跟weak類似,區(qū)別是被指向?qū)ο笙Ш?,屬性不?huì)自動(dòng)賦值為nil。

7.NSString的Retain和Copy的區(qū)別

Copy其實(shí)是建立了一個(gè)相同的對象,而retain不是:

比如一個(gè)NSString對象,地址為0×1111,內(nèi)容為@”STRING”

Copy到另外一個(gè)NSString之 后,地址為0×2222,內(nèi)容相同,新的對象retain為1, 舊有對象沒有變化

retain到另外一個(gè)NSString之 后,地址相同(建立一個(gè)指針,指針拷貝),內(nèi)容當(dāng)然相同,這個(gè)對象的retain值+1

簡單的說,二者的區(qū)別就是,Copy是內(nèi)存Copy,而retain是指針拷貝。

8.Weak指針置為nil的實(shí)現(xiàn)原理

Weak指針不會(huì)增加所引用對象的計(jì)數(shù),并在引用對象被回收的時(shí)候自動(dòng)被置為nil,這個(gè)通常用來解決循環(huán)引用的問題。

對象被釋放的時(shí)候, 其dealloc方法執(zhí)行之前, 它的所有weak屬性都已經(jīng)被設(shè)置為nil. 因此, 如果期望在dealloc里訪問weak屬性, 那是不行的.

內(nèi)部實(shí)現(xiàn) —— Weak表

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

在對象被回收的時(shí)候,經(jīng)過層層調(diào)用,會(huì)最終觸發(fā)下面的方法將所有Weak指針的值設(shè)為nil

簡單來說,這個(gè)方法首先根據(jù)對象地址獲取所以Weak指針地址的數(shù)組,然后遍歷這個(gè)數(shù)組把其中的數(shù)據(jù)設(shè)為nil,最后把這個(gè)entry從Weak表中刪除。

http://www.cnblogs.com/HypeCheng/p/4685443.html

9.__block和__weak

http://www.cnblogs.com/yajunLi/p/6203222.html?utm_source=itdadao&utm_medium=referral

block下循環(huán)引用的問題

__block本身并不能避免循環(huán)引用,避免循環(huán)引用需要在block內(nèi)部把__block修飾的obj置為nil

__weak可以避免循環(huán)引用,但是其會(huì)導(dǎo)致外部對象釋放了之后,block 內(nèi)部也訪問不到這個(gè)對象的問題,我們可以通過在 block 內(nèi)部聲明一個(gè) __strong

的變量來指向 weakObj,使外部對象既能在 block 內(nèi)部保持住,又能避免循環(huán)引用的問題

__block與__weak功能上的區(qū)別。

__block會(huì)持有該對象,即使超出了該對象的作用域,該對象還是會(huì)存在的,直到block對象從堆上銷毀;而__weak僅僅是將該對象賦值給weak對象,當(dāng)該對象銷毀時(shí),weak對象將指向nil;

__block可以讓block修改局部變量,而__weak不能。

另外,MRC中__block是不會(huì)引起retain;但在ARC中__block則會(huì)引起retain。所以ARC中應(yīng)該使用__weak。

10.可變屬性和不可變屬性

當(dāng)修飾可變屬性(如NSMutableArray,NSMutableDictionary,NSMutableString)時(shí),用Strong。

當(dāng)修飾不可變屬性時(shí),則用Copy。

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

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

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