在平常的iOS開發中,咱們天天都會使用到property,可是對於property的修飾符,可能你們跟我之前同樣,理解的不是特別透徹,如今就讓咱們來了解了解吧,數組
首先,一個property是能夠當作是:安全
property = 實例變量+setter方法+getter方法多線程
屬性修飾符會直接影響後續編譯器對於setter和getter方法的合成,屬性的修飾符分爲如下三類:異步
具有atomic特質的屬性,編譯器合成的setter和getter方法會加鎖,可以保證當多個線程在讀寫屬性時,老是可以獲取到屬性值,若是修飾符爲nonatomic,則不會對setter和getter方法加鎖,在一般狀況下,使用nonatomic不會帶來什麼問題,可是若是一個線程在屢次修改某個屬性時,另外一個線程去讀取屬性時,可能會取到未修改好的屬性,下面咱們將舉例來證實:atom
在這段代碼中,咱們有一個用nonatomic,strong修飾的數組dataArray,咱們在一個異步隊列的任務中持續地去修改這個屬性,在另外一個異步隊列的任務中持續地去讀取這個屬性,因爲dataArray是由strong來修飾的,那麼在dataArray的setter方法中,實際上是先保留新值,後釋放舊值,再將指針指向新值,因此在後面這個異步隊列的任務中,取到的dataArray多是一個已經被釋放的殭屍對象,因此會崩潰。線程
那麼還有一個問題3d
atomic是線程安全的嗎?指針
讓咱們先來了解一下線程安全的概念,cdn
多線程操做共享數據不會出現想不到的結果就是線程安全的,不然,是線程不安全的。對象
下面讓咱們來作個小實驗,
輸出結果爲:
咱們對在一個異步隊列的任務中,對dataArray屢次寫入,並在另外一個異步隊列中屢次讀取dataArray,從輸出結果中發現,獲得的結果並不同,因此使用atomic也並不能保證線程安全。
readwrite修飾的屬性只會合成setter和getter方法
readonly修飾的屬性只會合成getter方法,能夠以直接訪問實例變量的方式來完成賦值操做
這方面的修飾符主要是影響編譯器合成setter方法,
主要修飾基礎類型,使用assign修飾的屬性的setter方法主要是執行簡單的賦值操做
weak是ARC中新增長的屬性修飾符,主要定義一種「非擁有關係」,使用weak修飾的屬性的setter方法會既不保留新值,也不釋放舊值,不會使屬性指的對象的引用計數增長,當指向的對象被釋放時,屬性值也會被自動置爲nil。
strong是ARC中新增長的屬性修飾符,跟MRC時代中的retain修飾符很像,描述一種「擁有關係」,使用strong修飾的屬性的setter方法會先保留新值,再釋放舊值,最後把新值設置上。
unsafe_unretained與assign相似,可是用於對象類型,從字面意思上,也能看到,它是不安全,也不會強引用對象,因此它跟weak很類似,跟weak的區別在於當指向的對象被釋放時,屬性不會被置爲nil,因此是不安全的。
copy表達的語義類似,都會持有對象,可是它的setter方法不會保留新值,而是會調用對象的copy方法將新值拷貝一份,而後將它設置上,因此使用copy修飾的類型必須遵NSCopying協議,實現-(void)copyWithZone:(NSZone *)zone方法。