一、一些概念
淺Copy:指針的複制,隻是多了一個指向這塊記憶體的指針,共用一塊記憶體。
深Copy:記憶體的複制,兩塊記憶體是完全不同的,
也就是兩個對象指針分别指向不同的記憶體,互不幹涉。

atomic是Objc使用的一種線程保護技術,
基本上來講,是防止在寫未完成的時候被另外一個線程讀取,
造成資料錯誤。而這種機制是耗費系統資源的,
是以在iPhone這種小型裝置上,如果沒有使用多線程間的通訊程式設計,那麼nonatomic是一個非常好的選擇。
二、各種屬性的解析
weak:
<修飾Object類型,ARC下修飾delegate屬性>
1.在ARC環境下,所有指向這個對象的weak指針都将被置為nil。
這個特性很有用,很多codeer都有被指針指向已釋放的對象所造成的EXC_BAD_ACCESS困擾過,使用ARC以後,不論是strong還是weak類型的指針,都不會再指向一個已經銷毀的對象,從根本上解決了意外釋放導緻的crash。
2.修飾Object類型,修飾的對象在釋放後,指針位址會被置為nil,是一種弱引用。在ARC環境下,為避免循環引用,往往會把delegate屬性用weak修飾;在MRC下使用assign修飾。weak和strong不同的是:當一個對象不再有strong類型的指針指向它的時候,它就會被釋放,即使還有weak型指針指向它,那麼這些weak型指針也将被清除。
assign:
< 用于非指針變量。用于基礎資料類型 (例如NSInteger)和C資料類型(int, float, double, char, 等),另外還有id >
1.用于對基本資料類型進行複制操作,不更改引用計數。也可以用來修飾對象,但是,被assign修飾的對象在釋放後,指針的位址還是存在的,也就是說指針并沒有被置為nil,成為野指針。如果後續在配置設定對象到堆上的某塊記憶體時,正好分到這塊位址,程式就會crash。之是以可以修飾基本資料類型,因為基本資料類型一般配置設定在棧上,棧的記憶體會由系統自動處理,不會造成野指針。
我們常見的id delegate往往是用assign方式的屬性而不是retain方式的屬性,指派不會增加引用計數,就是為了防止delegation兩端産生不必要的循環引用。如果一個UITableViewController 對象a通過retain擷取了UITableView對象b的所有權,這個UITableView對象b的delegate又是a, 如果這個delegate是retain方式的,那基本上就沒有機會釋放這兩個對象了。自己在設計使用delegate模式時,也要注意這點。因為循環引用而産生的記憶體洩露也是Instrument無法發現的,是以要特别小心。
copy:
修飾NSString、NSArray、NSDictionary等有對應可變類型的對象
建立一個索引計數為1的對象,然後釋放舊對象。
是内容拷貝,會在記憶體裡拷貝一份對象,兩個指針指向不同的記憶體位址。一般用來修飾NSString、NSArray等有對應可變類型的對象,因為他們有可能和對應的可變類型(NSMutableString)之間進行指派操作,為確定對象中的字元串不被修改 ,應該在設定屬性是拷貝一份。而若用strong修飾,如果對象在外部被修改了,會影響到屬性。
在不可變對象之間進行轉換,strong與copy作用是一樣的,但是如果在不可變與可變之間進行操作,我比較推薦copy,這也就是為什麼很多地方用copy,而不是strong修飾NSString,NSArray等存在對應不可變類型的對象了,避免出現意外的資料操作.
strong
ARC下的strong等同于MRC下的retain都會把對象引用計數加1。
1.在ARC環境下,隻要某一對象被一個strong指針指向,該對象就不會被銷毀。如果對象沒有被任何strong指針指向,那麼就會被銷毀。在預設情況下,所有的執行個體變量和局部變量都是strong類型的。可以說strong類型的指針在行為上跟MRC下得retain是比較相似的
retain
釋放舊的對象,将舊對象的值賦予輸入對象,再提高輸入對象的索引計數為1
在MRC中,你需要自己retain一個想要保持的對象,ARC環境下就不需要了。現在唯一要做的就是用一個指針指向這個對象,隻要指針沒有被重置為空,對象就會一直在堆上。當指針指向新值的時候,原來的對象就會被release一次。這對執行個體變量,sunthesize的變量或者是局部變量都是實用的。
三、屬性之間差別
在iOS開發中我們知道一般nsstring,就用copy,定義一個模型對象,就用strong,隻是指派的,例如int、double、char 以及CGRect類似的就用assign。但具體為什麼可能很多人不是很清楚。
這裡進行簡單的解釋:
這些關鍵字基本上是針對屬性的set方法。
當用copy時,set方法會先release舊值,再copy一個新的對象,reference count 為1(減少了對上下文的依賴);當用assign,直接指派,無retain操作。當用retain,release舊值,retain新值;
strong與weak的差別
strong類似于retain,會将對象的引用計數器+1,配置設定記憶體位址。
weak類似于指針,隻是單純的指向某個位址,但是本身并未配置設定記憶體位址。當指向的位址被銷毀時,該指針會自動nil。
例子:
@synthesize string1;
@synthesize string2;
來猜一下,下面輸出是什麼?
self.string1 = [[NSString alloc] initWithUTF8String:"string 1"];
self.string2 = self.string1;
self.string1 = nil;
NSLog(@"String 2 = %@", self.string2);
結果是:String 2 = null
分析一下,由于self.string1與self.string2指向同一位址,且string2沒有retain記憶體位址,而 self.string1=nil釋放了記憶體,是以string1為nil。聲明為weak的指針,指針指向的位址一旦被釋放,這些指針都将被指派為 nil。這樣的好處能有效的防止野指針。在c/c++開發過程中,指針的空間釋放了後,都要将指針賦為NULL. 在這兒用weak關鍵字做了這一步。
assign和weak的差別
對于assign來說,一是非指針變量,比如說NSInteger之類的基礎資料類型、C資料類型,還有就是避免出現循環引用的時候,
對于weak,其和assign差不多,但是它多了一點,就是,它會自動對該類型變量設定為nil。
原文釋出時間為:2017-10-20
本文作者:佚名
本文來自雲栖社群合作夥伴“51CTO”,了解相關資訊可以關注。