objective-c中的copy關鍵字

前段時間突然被問到copy關鍵字的作用以及產生的效果,現在就來討論討論。

 

首先闡述兩個概念:

深複製:就是說複製時除了指針本身,對象內容也被複制了一份

淺複製:就是說只是複製了指針本身,對象內容並沒有被複制

 

一.集合對象的複製

以數組類型爲例,假設現在有一個數組:

NSArray *array =[NSArray arrayWithObjects:[Person new],[Person new],[Person new],[Person new], nil];

這個數組本身是不可變的,所以在調用copy方法時,就會是淺複製。

調用mutableCopy時,則是深複製,會生成一個新的可變數組,但是數組內部Person對象並沒有被複制

如若是一個可變數組:

NSMutableArray *mutableArray =[NSMutableArray arrayWithObjects:[Person new],[Person new],[Person new],[Person new], nil];

這個數組在調用copy和mutableCopy的效果是一樣的,都是深複製,但是copy方法得到的是新的不可變數組對象,而mutableCopy方法得到的是新的可變數組對象。同上數組內部Person對象並沒有被複制。

 

那麼集合類型怎麼做到內部對象也深複製呢?敲黑板劃重點來了:

如若想要集合內部對象深複製就要使用系統API:

- (instancetype)initWithArray:(NSArray<ObjectType> *)array copyItems:(BOOL)flag;

使用的時候flag必須傳YES,如果flag傳的是NO,那麼集合內部對象還是淺複製,但是雖說flag傳YES是深複製,也只能複製第一層元素對象,也就是說如果是雙重數組NSArray<NSArray<Person *> *> *類型的複製,那個Person對象還是不會被複制的。

並且,如果集合內部對象需要深複製,Person對象必須實現NSCoping協議,並實現copyWithZone:方法,否則這個方法會拋異常。

結論:

數組類型/複製類型 copy mutableCopy
NSArray 淺複製 深複製
NSMutableArray 深複製 深複製

 

二.自定義對象類型的複製

這個複製的話就得小心了,在使用之前必須要先實現NSCoping協議或NSMutableCoping協議,否則會因爲未實現copyWithZone:或者mutableCopyWithZone:方法而拋異常。

這個是否深複製就看方法內部如何實現的了,一般而言都是需要深複製的,不然copy就失去了它的意義。

舉個例子:

@interface Person : NSObject<NSCopying, NSMutableCopying>

@property(nonatomic, assign)NSInteger age;

@end
        
@implementation Person


- (nonnull id)copyWithZone:(nullable NSZone *)zone {
    Person *p = [[Person allocWithZone:zone] init];
    p.age = self.age;
    return self;
}

- (nonnull id)mutableCopyWithZone:(nullable NSZone *)zone {
    Person *p = [[Person allocWithZone:zone] init];
    p.age = self.age;
    return self;
}

@end

這樣的內部實現就是會深複製的了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章