object-c中的assign,retain,copy,atomic,nonatomic,readonly,readwrite以及strong,weak

來源:互聯網
上載者:User

標籤:

assign:指定setter方法用簡單的賦值,這是預設操作。你可以對標量類型(如int)使用這個屬性。你可以想象一個float,它不是一個對象,所以它不能retain、copy。assign指定setter方法用簡單的賦值,這是預設操作。你可以對標量類型(如int)使用這個屬性。你可以想象一個float,它不是一個對象,所以它不能retain、copy。

 

retain:指定retain應該在後面的對象上調用,前一個值發送一條release訊息。你可以想象一個NSString執行個體,它是一個對象,而且你可能想要retain它。retain釋放舊的對象,將舊對象的值賦予輸入對象,再提高輸入對象的索引計數為1 ,使用retain: 對其他NSObject和其子類 ,retain,是說明該屬性在賦值的時候,先release之前的值,然後再賦新值給屬性,引用再加1。

 

copy:指定應該使用對象的副本(深度複製),前一個值發送一條release訊息。基本上像retain,但是沒有增加引用計數,是分配一塊新的記憶體來放置它。

 

readonly:將只產生getter方法而不產生setter方法(getter方法沒有get首碼)。

 

readwrite:預設屬性,將產生不帶額外參數的getter和setter方法(setter方法只有一個參數)。

 

atomic:對於對象的預設屬性,就是setter/getter產生的方法是一個原子操作。如果有多個線程同時調用setter的話,不會出現某一個線程執行setter全部語句之前,另一個線程開始執行setter的情況,相關於方法頭尾加了鎖一樣。

 

nonatomic:不保證setter/getter的原子性,多線程情況下資料可能會有問題。


copy: 建立一個引用計數為1的對象,然後釋放舊的對象

retain:釋放舊的對象,將舊對象的值賦予輸入對象,再提高輸入對象的引用計數為 1

Copy其實是建立了一個相同的對象,而retain不是:
比如一個NSString對象,地址為0×1111,內容為@”STR”
Copy到另外一個NSString之 後,地址為0×2222,內容相同,新的對象retain為1, 舊有對象沒有變化

retain到另外一個NSString之 後,地址相同(建立一個指標,指標拷貝),內容當然相同,這個對象的retain值+1

也就是說,retain是指標拷貝,copy是內容拷貝。在拷貝之前,都會釋放舊的對象。

1、使用copy: 對NSString

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

 

strong與weak是由ARC新引入的物件變數屬性

ARC引入了新的對象的新生命週期限定,即零弱引用。如果零弱引用指向的對象被deallocated的話,零弱引用的對象會被自動化佈建為nil。



@property(strong) MyClass *myObject;

相當於@property(retain) MyClass *myObject;

@property(weak) MyOtherClass *delegate;

相當於@property(assign) MyOtherClass *delegate;
強引用與弱引用的廣義區別:
強引用也就是我們通常所講的引用,其存亡直接決定了所指對象的存亡。如果不存在指向一個對象的引用,並且此對象不再顯示列表中,則此對象會被從記憶體中釋放。
弱引用除了不決定對象的存亡外,其他與強引用相同。即使一個對象被持有無數個若引用,只要沒有強引用指向他,那麽其還是會被清除。



簡單講strong等同retain
weak比assign多了一個功能,當對象消失後自動把指標變成nil,好處不言而喻。



__weak, __strong 用來修飾變數,此外還有 __unsafe_unretained, __autoreleasing 都是用來修飾變數的。
__strong 是預設的關鍵詞。
__weak 聲明了一個可以自動 nil 化的弱引用。
__unsafe_unretained 聲明一個弱應用,但是不會自動nil化,也就是說,如果所指向的記憶體地區被釋放了,這個指標就是一個野指標了。
__autoreleasing 用來修飾一個函數的參數,這個參數會在函數返回的時候被自動釋放。

 

1. 假設你用malloc分配了一塊記憶體,並且把它的地址賦值給了指標a,後來你希望指標b也共用這塊記憶體,於是你又把a賦值給(assign)了b。此時a和b指向同一塊記憶體,請問當a不再需要這塊記憶體,能否直接釋放它?答案是否定的,因為a並不知道b是否還在使用這塊記憶體,如果a釋放了,那麼b在使用這塊記憶體的時候會引起程式crash掉。

2. 瞭解到1中assign的問題,那麼如何解決?最簡單的一個方法就是使用引用計數(reference counting),還是上面的那個例子,我們給那塊記憶體設一個引用計數,當記憶體被分配並且賦值給a時,引用計數是1。當把a賦值給b時引用計數增加到2。這時如果a不再使用這塊記憶體,它只需要把引用計數減1,表明自己不再擁有這塊記憶體。b不再使用這塊記憶體時也把引用計數減1。當引用計數變為0的時候,代表該記憶體不再被任何指標所引用,系統可以把它直接釋放掉。

3. 上面兩點其實就是assign和retain的區別,assign就是直接賦值,從而可能引起1中的問題,當資料為int, float等原生類型時,可以使用assign。retain就如2中所述,使用了引用計數,retain引起引用計數加1, release引起引用計數減1,當引用計數為0時,dealloc函數被調用,記憶體被回收。
4. copy是在你不希望a和b共用一塊記憶體時會使用到。a和b各自有自己的記憶體。
5. atomic和nonatomic用來決定編譯器產生的getter和setter是否為原子操作。在多線程環境下,原子操作是必要的,否則有可能引起錯誤的結果。加了atomic,setter函數會變成下面這樣:

[cpp] view plaincopy  
  1. <span style="font-size:14px;">if (property != newValue) {  
  2. [property release];  
  3. property = [newValue retain];  
  4. }</span>  
[cpp] view plaincopy  
  1.   

 

 

關於retain,copy,assign的區別問題其實困擾我很久了,因為在程式中不太常用到copy,assign,所以三者的具體差別一直不太明白。

按照我的理解,assign和retain的區別,就是引入了一個計數器retaincount,就可以對一個記憶體的釋放方便很多。copy,就是把原來的記憶體複製一遍,使各自都擁有一個記憶體,這樣釋放的時候也不會出錯。assign: 簡單賦值,不更改索引計數(Reference Counting)。copy: 建立一個索引計數為1的對象,然後釋放舊對象retain:釋放舊的對象,將舊對象的值賦予輸入對象,再提高輸入對象的索引計數為1使用assign: 對基礎資料類型 (NSInteger,CGFloat)和C資料類型(int, float, double, char, 等等)使用copy: 對NSString使用retain: 對其他NSObject和其子類nonatomic,非原子性訪問,不加同步,多線程並發訪問會提高效能。注意,如果不加此屬性,則預設是兩個存取方法都為原子型事務訪問 [cpp] view plaincopy  
  1. @property(nonatomic, retain) UITextField *userName //編譯時間自動產生的程式碼  
  2. - (UITextField *) userName {  
  3. return userName;  
  4. }  
  5.   
  6. - (void) setUserName:(UITextField *)userName_ {  
  7. [userName release];  
  8. userName = [userName_ retain];  
  9. }  
  10.   
  11.   
  12. @property(retain) UITextField *userName //自動產生的程式碼  
  13.   
  14. - (UITextField *) userName {  
  15. UITextField *retval = nil;  
  16. @synchronized(self) {  
  17. retval = [[userName retain] autorelease];  
  18. }  
  19. return retval;  
  20. }  
  21.   
  22. - (void) setUserName:(UITextField *)userName_ {  
  23. @synchronized(self) {  
  24. [userName release];  
  25. userName = [userName_ retain];  
  26. }  
  27. }  

object-c中的assign,retain,copy,atomic,nonatomic,readonly,readwrite以及strong,weak

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.