以前在沒有ARC(automatic reference counting)的時候我們使用assign與retain來修飾屬性呜呐,后來引入了更安全的weak和strong來修飾屬性
assign與weak
兩者都是弱引用统阿,assign通常用于普通類型屬性(如int,NSInteger),常見的還會用于delegate對象的屬性修飾诉稍,基本上來說兩者是可以通用的。
Q:那對于delegate的屬性修飾符到底是用assign好,還是weak好呢剂娄?
分析:weak在引用的對象被釋放的時候會將delegate置為nil鸯乃,而assign修飾的delegate依然會指向原來的位置鲸阻,這樣在delegate引用的對象被釋放后,delegate就會變成野指針缨睡。在OC中你給你一個nil對象發(fā)送消息不會crash鸟悴,但是給一個對象(如:野指針)發(fā)送他不能響應(yīng)的消息是會crash的,所以總的來說weak要比assign安全一些奖年。
retain和strong
他倆都是強(qiáng)引用细诸,除了某些情況下不一樣,比如修飾block陋守,其他的時候也是可以通用的震贵。
結(jié)論
- 只要不引入外部變量利赋,無論是MRC還是ARC,無論是retain還是strong修飾block猩系,block屬性都是存在全局?jǐn)?shù)據(jù)區(qū)
- 引入外部變量時媚送,retain和strong(copy)是有區(qū)別的,
在MRC時寇甸,block存在棧區(qū)(stack)的塘偎,因此使用的時候要注意此時的block是否還存在,以免操作了野指針而閃退拿霉。
在ARC時吟秩,block是存在堆區(qū)(heap)的。
(外部變量可以是局部變量友浸,也可以是一個屬性)
總結(jié)
所以說block的屬性修飾符應(yīng)該用strong或copy比較安全些峰尝。
對block來說,屬性修飾符用strong或copy效果是一樣的收恢。
其他屬性關(guān)鍵字總結(jié)
1.讀寫權(quán)限:readonly,readwrite(默認(rèn))
2.原子性: atomic(默認(rèn))武学,nonatomic。
atomic讀寫線程安全伦意,但效率低火窒,也不是絕對的安全,如果修飾的是數(shù)組驮肉,那么對數(shù)組的讀寫是安全的熏矿,但如果是操作數(shù)組進(jìn)行添加移除對象,就不保證安全了离钝。
3.引用計數(shù):
retain/strong 引用計數(shù)加1
assign
修飾基本數(shù)據(jù)類型票编,修飾對象類型時,不改變其引用計數(shù)卵渴,會產(chǎn)生野指針慧域,修飾的對象在被釋放后,assign指針仍然指向原對象內(nèi)存地址浪读,如果使用assign指針繼續(xù)訪問原對象的話昔榴,就可能會導(dǎo)致內(nèi)存泄漏或程序異常weak
不改變被修飾對象的引用計數(shù),所指對象在被釋放后碘橘,weak指針會自動置為nil
(weak的實(shí)現(xiàn)原理是什么互订?當(dāng)引用對象銷毀是它是如何管理內(nèi)部的Hash表的?
runTime會把對weak修飾的對象放到一個全局的哈希表中痘拆,用weak修飾的對象的內(nèi)存地址為key仰禽,weak指針為值,在對象進(jìn)行銷毀時,用通過自身地址去哈希表中查找到所有指向此對象的weak指針坟瓢,并把所有的weak指針置位nil勇边。-
copy:分為深拷貝和淺拷貝
深拷貝:對對象內(nèi)容的復(fù)制折联,開辟新的內(nèi)存空間
淺拷貝:對內(nèi)存地址的復(fù)制犹撒,讓目標(biāo)對象指針和原對象指向同一片內(nèi)存空間會增加引用計數(shù)
總結(jié)
可變對象的copy和mutableCopy都是深拷貝
不可變對象的copy是淺拷貝,mutableCopy是深拷貝
copy方法返回的都是不可變對象
- @property (nonatomic, copy) NSMutableArray * array;這樣寫有什么影響识颊?
因?yàn)閏opy方法返回的都是不可變對象诚镰,所以array對象實(shí)際上是不可變的,如果對其進(jìn)行可變操作如添加移除對象祥款,則會造成程序crash