property中的屬性關鍵字

ARC下,不顯式指定任何屬性關鍵字時,默認的關鍵字都有哪些?

atomicreadwritestrong(對象)、assgin(基本數據類型)。

具體比較分析:

1、atomic與nonatomic

atomic:默認是有該屬性的,這個屬性是爲了保證程序在多線程情況下,編譯器會自動生成一些加鎖代碼,避免該變量的讀寫不同步的問題,提供多線程安全。

nonatomic:如果該對象無需考慮多線程的情況,加入這個屬性,這樣會讓編譯器少生成一些加鎖代碼,禁止多線程,變量保護,提高性能和效率。

注:atomic是Objc使用的一種線程保護技術,基本上來講是防止在寫未完成的時候另一個線程讀取,造成的數據錯誤。而這種機制是非常耗費系統資源的,所以iPhone這種小型設備上,如果沒有使用多線程間的通訊編程,那麼nonatomic是一個非常好的選擇。而iOS開發中,普遍使用nonatomic也是基於性能這一點。

擴展:

自旋鎖和互斥鎖

共同點: 都可以鎖定一段代碼。同一時間,只有線程能夠執行這段鎖定的代碼。

區別:互斥鎖,在鎖定的時候,其他線程會睡眠,等待條件滿足,再喚醒。

自旋鎖,在鎖定的時候,其他的線程會做死循環,一直等待這條件滿足,一旦條件滿足,立馬去執行,少了一個喚醒過程。

2、readwrite與readonly

readwrite:這個屬性是默認的情況,會自動爲你生成存取器。

readonly:只生成getter,不會生成setter方法。

注:

readwrite、readonly這兩個屬性的真正價值,不是提供成員變量的訪問接口,而是控制成員變量的訪問權限。

3、strong與weak

strong:強引用,也是我們通常說的引用,其存亡直接決定了所指向對象的存亡,當強引用指向了某個對象,那便擁有了這個對象。如果不存在指向一個對象的引用,並且此對象不再使用,則對象就會被從內存中釋放掉。默認所有實例變量和局部變量都是strong指針。

weak:弱引用,不決定對象的存亡,只是單純的引用了某個對象但是並不擁有該對象。即使一個對象被持有無數個弱引用,只要沒有強引用指向它,那麼還是會被清除。

注:

strong與retain功能相似;weak與assign相似,只是當對象消失後weak會自動把指針置爲nil,避免了野指針的產生,因而weak屬性就不需要在dealloc中置nil了。

4、assign和weak

weak 此特質表明該屬性定義了一種“非擁有關係” (nonowning relationship)。爲這種屬性設置新值時,設置方法既不保留新值,也不釋放舊值。此特質同assign類似, 然而在屬性所指的對象遭到摧毀時,屬性值也會清空(nil out)。 而 assign 的“設置方法”只會執行鍼對“純量類型” (scalar type,例如 CGFloat 或 NSlnteger 等)的簡單賦值操作。

 weak 必須用於 OC 對象,而assign 可以用非 OC 對象。

使用assign: 對基礎數據類型 (NSInteger,CGFloat)和C數據類型(int, float, double, char, 等等)

注:

1.修飾變量類型的區別

weak只可以修飾對象。如果修飾基本數據類型,編譯器會報錯-“Property with ‘weak’ attribute must be of object type”。

assign可修飾對象,和基本數據類型。當需要修飾對象類型時,MRC時代使用unsafe_unretained。當然,unsafe_unretained也可能產生野指針,所以它名字是"unsafe_”。

2.是否產生野指針的區別

weak不會產生野指針問題。因爲weak修飾的對象釋放後(引用計數器值爲0),指針會自動被置nil,之後再向該對象發消息也不會崩潰。 weak是安全的。

assign如果修飾對象,會產生野指針問題;如果修飾基本數據類型則是安全的。修飾的對象釋放後,指針不會自動被置空,此時向對象發消息會崩潰。

assign適用於基本數據類型如int,float,struct等值類型,不適用於引用類型。因爲值類型會被放入棧中,遵循先進後出原則,由系統負責管理棧內存。而引用類型會被放入堆中,需要我們自己手動管理內存或通過ARC管理。

weak適用於delegate和block等引用類型,不會導致野指針問題,也不會循環引用,非常安全。

5、copy和retain

assgin:默認類型,setter方法直接賦值,不進行任何的retain操作,不改變引用計數。一般用來處理基本數據類型。

retain:釋放舊的對象(release),將舊對象的值賦給新對象,再令新對象引用計數爲1。可理解爲指針拷貝。

copy:與retain的流程一樣,先對舊的值release,再copy出新的對象,引用計數爲1,爲了減少對上下文的依賴而引入的機制。可以理解爲內容的拷貝,也就意味着內容被copy後,內存中會有兩個存儲空間存儲同樣的內容。

對copy屬性要特別注意:被定義有copy屬性的對象必須要 符合NSCopying協議,必須實現- (id)copyWithZone:(NSZone *)zone方法。對copy屬性要特別注意:被定義有copy屬性的對象必須要 符合NSCopying協議,必須實現- (id)copyWithZone:(NSZone *)zone方法。

對於不可變對象來說,copy爲淺拷貝,和strong一樣,均增加了源對象的引用計數;而對於可變對象來說,copy爲深拷貝,我們知道深拷貝爲內容拷貝,所以如果改變源對象時,聲明成copy的屬性並不會跟着變化。而由於聲明成strong的屬性只是增加源對象的引用計數,依舊指向源對象,故會同步改變。所以,當我們聲明屬性時,如果不希望它因爲源對象(源對象爲可變對象時)的改變而改變,則用copy修飾。

擴展

深拷貝與淺拷貝

深拷貝就是內容拷貝,淺拷貝就是指針拷貝

其實copy本質是用來做深拷貝的,但是修飾不可變的數組時,由於深拷貝出來也不能做添加或刪除操作,爲了節約資源,直接淺拷貝了。

深拷貝就是拷貝出和原來僅僅是值一樣,但是內存地址完全不一樣的新的對象,創建後和原對象沒有任何關係。

淺拷貝就是拷貝指向原來對象的指針,使原對象的引用計數+1,可以理解爲創建了一個指向原對象的新指針而已,並沒有創建一個全新的對象。

[immutableObject copy] //淺複製

[immutableObject mutableCopy] //單層深複製

[mutableObject copy] //單層深複製

[mutableObject mutableCopy] //單層深複製

注:

使用copy: 對NSString

使用retain: 對其他NSObject和其子類

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章