一、深copy、淺copy
淺拷貝是指源對象與拷貝對象共用一份實體,僅僅是引用的變量不同(名稱不同)。對其中任何一個對象的改動都會影響另外一個對象。舉個例子,一個人一開始叫張三,后來改名叫李四了,可是還是同一個人,不管是張三缺胳膊少腿還是李四缺胳膊少腿,都是這個人倒霉。
深拷貝是指源對象與拷貝對象互相獨立,其中任何一個對象的改動都不會對另外一個對象造成影響。舉個例子,一個人名叫張三,后來用他克?。僭O(shè)法律允許)了另外一個人,叫李四,不管是張三缺胳膊少腿還是李四缺胳膊少腿都不會影響另外一個人。
二、對于數(shù)組本身來說
1、對NSArray的copy和mutableCopy操作。

由上圖可以得知:
- array1是初始化的不可變數(shù)組。
- array2和array9是不可變數(shù)組,指針指向的內(nèi)存地址和array1指向內(nèi)存地址相同。
- array8和array10是可變數(shù)組,指針指向的內(nèi)存地址和array1的不同。
(控制臺的__NSArrayI表示不可變。__NSArrayM表示可變。)
結(jié)論1:
1、對于NSArray不可變數(shù)組進行copy和mutableCopy操作,結(jié)果和 “=” 左邊無關(guān),最終的和右邊進行的操作有關(guān)(主要是因為OC的動態(tài)性。動態(tài)類型。 如id類型。實際上靜態(tài)類型因為其固定性和可預(yù)知性而使用得更加廣泛。靜態(tài)類型是強類型,而動態(tài)類型屬于弱類型。運行時決定接收者)。
2、copy操作后的指針2和9指向了1指向的內(nèi)存地址(這塊地址內(nèi)存保存的數(shù)據(jù)是數(shù)組內(nèi)的內(nèi)容信息),mutableCopy操作后的指針8和10分別指向了不同的內(nèi)存地址(這兩塊不同的地址內(nèi)存保存的數(shù)據(jù)和1一樣)
2、對NSMutableArray的copy和mutableCopy的操作。

由上圖得知
- array3是初始化的可變數(shù)組。
- array4和array5是不可變數(shù)組,指針指向的內(nèi)存地址和array3指向的內(nèi)存地址不同。
- array6和array7是可變數(shù)組,指針指向的內(nèi)存地址和array3的不同。
結(jié)論2:
對于NSMutableArray可變數(shù)組進行copy和mutableCopy操作,最終得到的4個內(nèi)存地址都不一樣。
對NSArray和NSMutableArray進行copy和mutableCopy操作總結(jié)
- [NSArray copy] 淺copy
- [NSArray mutableCopy] 深copy
- [NSMutableArray copy] 深copy
- [NSMutableArray mutableCopy] 深copy
- **具體實現(xiàn)具體分析,不可一概而論,尤其是自己實現(xiàn)copy和mutableCopy功能時。
三、數(shù)組保存的對象

由上圖得知:
- tmp1初始化,內(nèi)存引用計數(shù)+1,數(shù)組使保存對象的引用計數(shù)+1,retain +1。
- tmp4獲取并修改了數(shù)組第一項數(shù)據(jù),那么數(shù)組內(nèi)部的第一項元素以及tmp1都做了修改,以及上一條可知,數(shù)組保存的是數(shù)組內(nèi)部對象的指針。

出錯是在46行
NSArray *eArray = [[NSArray alloc] initWithArray:array copyItems:YES];錯誤信息是指UIView沒有實現(xiàn)copyWithZone:函數(shù)

由UIView的頭文件可以看出,UIView沒有實現(xiàn)NSCoping和NSMutableCoping協(xié)議。


為UIView添加擴展,實現(xiàn)NSCopying協(xié)議。

可以看到程序順利運行,并且擴展中
copyWithZone:函數(shù)執(zhí)行了6次。從上圖可以看到,eArray和mfArray調(diào)用的是
initWithArray:copyItems:函數(shù),由字面意思可知,新創(chuàng)建一個數(shù)組,同時copy數(shù)組內(nèi)部保存的對象。

測試結(jié)果可知array1、2、3保存的對象地址和str1、2的地址一樣,4 copyItem之后的不一樣,str1、2修改了值,array1、2、3跟著也修改了,4沒變。
(兩個NSMutableString初始化之后為什么地址一樣?array4中保存的NSTaggedPointerString是什么類型的指針?有了解的請告知。謝謝)
總結(jié):“
OC是一切皆對象的編程思想”
- 數(shù)組會對保存的對象內(nèi)存引用計數(shù)+1。
- 數(shù)組保存的是對象的指針對象。
- 如果數(shù)組copy時,保存的對象也想同時copy,可以用
initWithArray:copyItems:函數(shù)。(肯定還有其他辦法?)
4、NSDictionary和NSMutableDictionary
保存的內(nèi)容value和數(shù)組一樣,key是固定的NSTaggedPointerString類型,同樣存在initWithDictionary:copuItems:函數(shù)。
5、線程安全
NSArray和NSDictionary是線程安全的
NSMutableArray和NSMutableDictionary是線程不安全的。
6、對NSArray、NSDictionary賦值
對這類集合對象賦值時,不能為空nil,如果賦空值,則會崩潰。如果定義了一個NSArray,為其分配了內(nèi)存,又想設(shè)置其中的內(nèi)容為空,則可以用 [NSNULL null] 返回的對象來初始化NSArray中的內(nèi)容。