nsdictionary
物件,新增內容,然後通過**產生可變和不可變副本,這些複製是深複製還是淺複製?那麼對於可變物件呢?為什麼nsstring定義屬性時需要用copy呢?copy屬性和copy物件有什麼不同?
首先先說一下
copy
和retain
的區別:
copy
是建立乙個新物件,是內容拷貝。
retain
是建立乙個指標,引用物件計數加1。
retain
屬性表示兩個物件位址相同(建立乙個指標,指標拷貝),內容當然相同,這個物件的
retain
值+1。
對於深複製和淺複製我們來看下面的**:
nsdictionary
*dict = [
nsdictionary
dictionarywithobjectsandkeys
:@"1"
,@"1"
,@"2"
,@"2"
,nil];
nslog(@"
原字典:%p"
,dict);
nsdictionary
*dictretain = dict.
retain;
nslog(@"
計數器:%p"
,dictretain);
nsdictionary
*dictcopy = dict.
copy;
nslog(@"
淺複製:%p"
,dictcopy);
nsmutabledictionary
*dictmutablecopy = dict.
mutablecopy;
nslog(@"
深複製:%p"
,dictmutablecopy);
列印結果:
原字典:0x7f7f89d21ec0
計數器:0x7f7f89d21ec0
淺複製:0x7f7f89d21ec0
深複製:0x7f7f89c09680
也就是說,
對於retain
和copy
產生的字典記憶體與原位址記憶體相同,也就是說
copy
產生的不可變版本是淺複製和
retain
一樣拷貝的是指標。而
mutablecopy
深複製是拷貝的物件內容。
下面我們看乙個可變物件的拷貝過程:
nsmutablestring
*string = [
nsmutablestring
stringwithstring
:@"name"];
nslog
(@"strp:%p"
,string);
nsstring
*stringcopy = [string
copy];
nslog
(@"copy:%p"
,stringcopy);
nsmutablestring
*mstringcopy = [string
copy];
nslog
(@"copy:%p"
,mstringcopy);
nsmutablestring
*stringmcopy = [string
mutablecopy];
nslog
(@"mcopy:%p"
,stringmcopy);
列印結果:
strp:0x7faea1f124d0
copy:0xa000000656d616e4
copy:0xa000000656d616e4
mcopy:0x7faea1e0df20
對於可變物件進行複製,結果和上面不一樣了。
我們可以這樣理解:
如果對一不可變物件複製,
copy
是指標複製(淺拷貝)和
mutablecopy
就是物件複製(深拷貝)。如果是對可變物件複製,都是深拷貝,但是
copy
返回的物件是不可變的。
還有乙個問題就是:我們知道,在
@property
屬性裡copy
說的是複製了乙個新的物件,引用計數不加
1.那麼這裡屬性
copy
則是使用了深複製。而呼叫
copy
方法則是做了乙個淺複製。
這也就是為什麼
nsstring
屬性變數要用
copy
關鍵字。
如果把乙個
nsstring
賦值給nsmutablestring
屬性時,如果使用了
strong,
則相當於淺複製。兩個指標指向同一塊記憶體,當
nsmutablestring
改變後,
nsstring
也就改變了。如果使用了
copy
,則是深複製。兩個物件存在於不同的記憶體中,當
nsmutablestring
改變時,不影響
nsstring.
另外,對於字串來說,我們在使用的時候還要注意:
initwithformat
會建立新空間,
initwithstring
不一定建立新空間,取決於引數。如果後面是常量字串則不會建立新空間,如果是定義新字串,則會建立新空間。
下面是測試**:
nsstring *name = [[nsstring alloc]initwithformat:@"
張三"];
nsstring
*name = [[
nsstring
alloc
]initwithstring:@"
張三"];
nslog
(@"%ld"
,[name
retaincount
]);
[name
retain];
nslog
(@"%ld"
,[name
retaincount
]);
[name
copy];
nslog
(@"%ld"
,[name
retaincount
]);
[name
mutablecopy];
nslog
(@"%ld"
,[name
retaincount])
結果:如果是
initwithstring,
則輸入結果全為
-1,如果是
initwithformat
,結果分別是
:1,2,3,4
iOS深複製和淺複製
淺複製示例 nsmutablearray marray nsmutablearray arraywithobjects nsmutablestring stringwithstring origiona nsmutablestring stringwithstring origionb nsmuta...
iOS 深複製和淺複製
一 copy與retain的區別 1 copy是建立乙個新物件,retain是建立乙個指標,引用物件計數加一。2 copy屬性表示兩個物件內容相同,新的物件retain為1,與舊有的物件的引用計數無關,舊有物件沒有改變。copy減少物件對上下文的依賴。3 retain屬性表示兩個物件位址相同 建立乙...
淺複製和深複製
在c 中,下面三種物件需要呼叫拷貝建構函式 有時也稱 複製建構函式 1 乙個物件作為函式引數,以值傳遞的方式傳入函式體 全域性函式,傳入的是物件 void g fun resume c 2 乙個物件作為函式返回值,以值傳遞的方式從函式返回 全域性函式 返回的是物件 resume g fun 3 乙個...