[底層原理]關於iOS中property修飾符我的的一點理解

在平常的iOS開發中,咱們天天都會使用到property,可是對於property的修飾符,可能你們跟我之前同樣,理解的不是特別透徹,如今就讓咱們來了解了解吧,數組

首先,一個property是能夠當作是:安全

property = 實例變量+setter方法+getter方法多線程

屬性修飾符會直接影響後續編譯器對於setter和getter方法的合成,屬性的修飾符分爲如下三類:異步

1.原子性

atomic VS nonatomic

具有atomic特質的屬性,編譯器合成的setter和getter方法會加鎖,可以保證當多個線程在讀寫屬性時,老是可以獲取到屬性值,若是修飾符爲nonatomic,則不會對setter和getter方法加鎖,在一般狀況下,使用nonatomic不會帶來什麼問題,可是若是一個線程在屢次修改某個屬性時,另外一個線程去讀取屬性時,可能會取到未修改好的屬性,下面咱們將舉例來證實:atom



使用nonatomic修飾dataArray,會崩潰



使用atomic修飾dataArray,不會崩潰

在這段代碼中,咱們有一個用nonatomic,strong修飾的數組dataArray,咱們在一個異步隊列的任務中持續地去修改這個屬性,在另外一個異步隊列的任務中持續地去讀取這個屬性,因爲dataArray是由strong來修飾的,那麼在dataArray的setter方法中,實際上是先保留新值,後釋放舊值,再將指針指向新值,因此在後面這個異步隊列的任務中,取到的dataArray多是一個已經被釋放的殭屍對象,因此會崩潰。線程

那麼還有一個問題3d

atomic是線程安全的嗎?指針

讓咱們先來了解一下線程安全的概念,cdn

多線程操做共享數據不會出現想不到的結果就是線程安全的,不然,是線程不安全的。對象

下面讓咱們來作個小實驗,


對用atomic修飾的數組連續修改時,讀取屬性

輸出結果爲:


輸出結果

咱們對在一個異步隊列的任務中,對dataArray屢次寫入,並在另外一個異步隊列中屢次讀取dataArray,從輸出結果中發現,獲得的結果並不同,因此使用atomic也並不能保證線程安全。

2.讀/寫權限

readwrite VS readonly

readwrite修飾的屬性只會合成setter和getter方法

readonly修飾的屬性只會合成getter方法,能夠以直接訪問實例變量的方式來完成賦值操做

3.內存管理

這方面的修飾符主要是影響編譯器合成setter方法,

assign

主要修飾基礎類型,使用assign修飾的屬性的setter方法主要是執行簡單的賦值操做

weak

weak是ARC中新增長的屬性修飾符,主要定義一種「非擁有關係」,使用weak修飾的屬性的setter方法會既不保留新值,也不釋放舊值,不會使屬性指的對象的引用計數增長,當指向的對象被釋放時,屬性值也會被自動置爲nil。

strong

strong是ARC中新增長的屬性修飾符,跟MRC時代中的retain修飾符很像,描述一種「擁有關係」,使用strong修飾的屬性的setter方法會先保留新值,再釋放舊值,最後把新值設置上。

unsafe_unretained

unsafe_unretained與assign相似,可是用於對象類型,從字面意思上,也能看到,它是不安全,也不會強引用對象,因此它跟weak很類似,跟weak的區別在於當指向的對象被釋放時,屬性不會被置爲nil,因此是不安全的。

copy

copy表達的語義類似,都會持有對象,可是它的setter方法不會保留新值,而是會調用對象的copy方法將新值拷貝一份,而後將它設置上,因此使用copy修飾的類型必須遵NSCopying協議,實現-(void)copyWithZone:(NSZone *)zone方法。

相關文章
相關標籤/搜索