objective-c - NSArray *array = otherarray;是深拷貝還是淺拷貝?該怎麼理解
PHPz
PHPz 2017-04-24 09:11:20
0
2
484
<小時>
NSArray *array = [[NSArray alloc] initWithObjects:@23, @"re", nil] ;
NSArray *arr2 = 陣列;
NSLog(@"%lu",(unsigned long)[數組retainCount]);
NSLog(@"%head",(unsigned long)[arr2 keepCount]);

能源1,1

<前> <程式碼> NSArray *array = [[NSArray alloc] initWithObjects:@23, @"re", nil] ; NSArray *arr2 = [陣列副本]; NSLog(@"%lu",(unsigned long)[數組retainCount]); NSLog(@"%head",(unsigned long)[arr2 keepCount]);

能源2.2

<前> <程式碼> NSArray *array = [[NSArray alloc] initWithObjects:@23, @"re", nil] ; NSArray *arr2 = [陣列可變複製]; NSLog(@"%lu",(unsigned long)[數組retainCount]); NSLog(@"%head",(unsigned long)[arr2 keepCount]);

能源1,1

你的手機有什麼用?

PHPz
PHPz

学习是最好的投资!

全部回覆(2)
PHPzhong
NSArray *arr2 = array;

上面這段程式碼,既不是深拷貝也不是淺拷貝,這只是一個指標賦值,它們指向的是同一塊記憶體。


NSArray *arr2 = [array copy];

上面這段程式碼,理論上 array 创建了一份浅拷贝,可实际上并没有发生任何拷贝,仅仅做了一次 retain

這是因為 NSArray 是一个不可被修改的只读数组,它在实现 NSCopying protocol 的时候很机(tou)智(lan)的仅仅做了一次 retain 而没有创建任何新对象,所以造成 arrayarr2 引用計數都變成 2,有些違反直覺。

注意,此時 arrayarr2 是指向同一片記憶體的,透過列印指標位址可以明顯的看出來。


NSArray *arr2 = [array mutableCopy];

上面這段程式碼,mutableCopy 返回的是一个 NSMutableArray,这时候 NSArray 没什么巧可取,就是老老实实的创建了一个新的 NSMutableArray 对象,array 指向 NSArrayarr2 指向新创建的 NSMutableArray,所以引用計數都是 1。


回到深拷貝和淺拷貝,對於一個容器來說,如果拷貝時容器裡面的對象僅僅增加了引用計數,那麼就是淺拷貝;否則,如果為每一個對象創建了新對象,那麼就是深拷貝。

題主應該用 NSMutableArray 来尝试才能得到清晰正确的结果,NSArray 這種 immutable 的容器無法看出想要的效果。

順便一提,NSMutableArraycopy 是淺拷貝。

洪涛

說句題外話,斷點、LLDB調試或列印觀察記憶體位址,可以幫助我們更好的理解這裡面的機制。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板