copy 和 mutableCopy的區別

2021-10-02 13:52:03 字數 1955 閱讀 3952

1.字串拷貝

copy淺拷貝,不拷貝物件本身,僅僅是拷貝指向物件的指標。

nsstring *str1 = @"qqq";

nsstring *str2 = [str1 copy];

nslog(@"\nstr1 = %@ str1p = %p \n str2 = %@ str2p = %p", str1, str1, str2, str2);

//執行結果

//執行結果sss---qqq----0x1080a4140---0x1080a4100

那為什麼nsstring *str2 = [str1 copy];是不同的指標指向同一塊記憶體空間,str1從新賦值後兩個記憶體空間就不一樣了呢?

因為str2 = str1的時候,兩個字串都是不可變的,指向的同一塊記憶體空間中的@"str1",是不可能變成@"abcd"的。所以這個時候,為了優化效能,系統沒必要另外提供記憶體,只生成另外乙個指標,指向同一塊記憶體空間就行。

但是當你從新給str1或者str2賦值的時候,因為之前的內容不可變,還有互不影響的原則下,這個時候,系統會從新開闢一塊記憶體空間。

nsmutablestring *mstr1 = [[nsmutablestring alloc]initwithstring:@"123"];

nsmutablestring *mstr2 = [mstr1 copy];

nslog(@"%@---%@--%p---%p",mstr1,mstr2,mstr1,mstr2);

nsmutablestring *mstr3 = [mstr1 mutablecopy];

nslog(@"%@---%p",mstr3,mstr3);

copy 和 mutablecopy   當 immtable 物件呼叫copy方法 返回的是 immtable物件   immtable 呼叫 mutablecopy返回 mutable

2.相對陣列而言

@property (nonatomic, copy) nsmutablearray *marr;

nsarray *arr = @[@"123", @"456", @"asd"];

self.marr = [arr mutablecopy];

nslog(@"\n arrp = %p \n self.marrp = %p, self.marr class = %@", arr, self.marr, [self.marr class]);

可以看出記憶體位址不一樣,但是_marr是不可變的陣列。

因為_marr宣告的時候是用copy修飾,那麼就限制了他為不可變的陣列。 賦值的時候是用mutablecopy,可變陣列的複製方法,所以會從新分配記憶體。

//執行結果  

arrp = 0x600003a6ebb0

self.marrp = 0x600003a6eb20, self.marr class = __nsarrayi

深入物件的copy和mutableCopy

深入理解copy和mutablecopy必須要先理解堆 heap 和棧 stack 的區別,以下鏈結來自stack overflow的詳細解答。簡要的一句話就是 物件儲存在堆中,該物件在堆中便有了乙個記憶體位址,該位址屬於棧中的乙個變數 指標 這個變數在棧中也占有一段記憶體。對於不可變物件copy是...

retain和copy的區別

當手動進行記憶體管理時,對於 物件,在 方法中可以使用 對於普通 物件使用 對於 使用 retain 使當前物件的引用計數 1,在 物件中使用 copy 建立乙個物件副本,和呼叫 方法的物件不是同乙個,常常在 中使用 深複製 mutablecopy 深拷貝為物件拷貝,原來的物件計數器不變。淺複製 淺...

assign retain和copy的區別

一 assign屬性 當資料型別為int float等原生型別時,可以使用assign,否則可能導致記憶體洩露。例如當使用malloc分配了一塊記憶體,並把它的位址賦值給了指標a,後來如果希望指標b也共享這塊記憶體,於是講a賦值給 assgin b。這時就用到了assgin,此時a和b指向同一塊記憶...