天天看點

objective-c中對象複制的幾種情況

objective-c中有NSCopying和NSMutableCopying兩種協定,分别定義了copy和mutableCopy兩個方法。

如果某個類要實作這兩種對象拷貝,必須實作上述兩個協定。

首先我們要搞清楚copy和mutalbeCopy的差別。

衆所周知,objective-c中,有NSString和NSMutableString,NSArray和NSMutableArray等等配對的類。

其中前者是不可變的類(沒有set,add,append等方法),後者是可變的類(有set,add,append等方法)。

copy和mutableCopy的差別在于它們的傳回值是不可變類型還是可變類型。

不管被複制的對象是不可變的還是可變的,copy的傳回值類型始終是不可變類型。

同樣,不管被複制的對象是不可變的還是可變的,mutableCopy的傳回值類型始終是可變類型的。

比如,

NSArray *array = [[NSArray alloc] init];

id arr1 = [array copy]; // arr1是NSArray類型

id arr2 = [array mutableCopy]; // arr2是NSMutableArray類型

再比如,

NSMutableArray *array = [[NSMutableArray alloc] init];

id arr1 = [array copy]; // arr1是NSArray類型

id arr2 = [array mutableCopy]; // arr2是NSMutableArray類型

另外還有個深複制和淺複制的問題,

一般的複制都是淺複制,也就是隻複制對象類本身,該類所參照的對象不複制。

但是不可變類的copy函數,其實并沒有複制,而隻是把指針複制了一下,我們把它稱為指針複制。

比如,

NSArray *array = [[NSArray alloc] init];

id arrCopy = [array copy];

此時,arrCopy和array指向同一個記憶體空間,用arrCopy==array作判斷條件是成立的。

且此時arrCopy和array的retainCount是2,說明該複制隻是把retainCount+1,并沒有真正複制記憶體。

這樣做其實是有道理的,因為NSArray是不可變的,即使不真正複制記憶體,也不影響其當做複制的來正常使用。

但NSArray的mutableCopy、NSMutableArray的copy和mutableCopy是真正的複制記憶體,而且是淺複制。

其它可變類型和不可變類型的copy和mutableCopy也遵循同樣的規則。