1.NSCopying ————> - (id)copy;
NSCopying是一個與對象拷貝有關的協議。若是想讓一個類的對象支持拷貝,就須要讓該類實現NSCopying協議。
NSCopying協議中的聲明的方法只有一個- (id)copyWithZone:(NSZone *)zone。
當咱們的類實現了NSCopying協議,經過類的對象調用copy方法時,copy方法就會去調用咱們實現的- (id)copyWithZone:(NSZone *)zone方法,實現拷貝功能。
- (id)copyWithZone:(NSZone *)zone{
PersonModel *model = [[[self class] allocWithZone:zone] init];
model.firstName = self.firstName;
model.lastName = self.lastName;
//未公開的成員 model->_nickName = _nickName; return model;
}
說明:在- (id)copyWithZone:(NSZone *)zone方法中,必定要經過[self class]方法返回的對象調用allocWithZone:方法。
由於指針可能實際指向的是PersonModel的子類。這種狀況下,經過調用[self class],就能夠返回正確的類的類型對象。
- //無子類是能夠這樣實現
- Fraction *newFract = [[Fraction allocWithZone:zone] init];
- //有子類時,須要這樣實現
- Fraction *newFract = [[[self class] allocWithZone:zone] init];
舉例:
例如:
B = A.copy.
對對象進行copy操做,會獲得一個新的對象,可是其屬性,其指針跟以前是同一個地址。
A屬性值改變時,同一個地址B的值也會改變。
A屬性地址若是變了,B的值不會受到影響。B仍是指向原先的地址。
注意: NSString , NSArray,NSDictionary,NSSet 進行copy 不會產生新的對象。
2.NSMutableCopying - (id)mutableCopy;
NSCopying協議與NSMutableCopying的區別主要是在於,返回的對象是不是可變類型的。以Foundation框架的NSArray爲例
NSArray *nameArray = @[@"Jim", @"Tom", @"David"];
NSArray *copyArray = [nameArray copy];
NSMutableArray *mutableCopyArray = [nameArray mutableCopy];
[mutableCopyArray addObject:@"Sam」]
NSArray對象調用copy方法時,copy方法會調用- (id)copyWithZone:(NSZone *)zone,獲得對象的一份拷貝,但獲得的對象仍是不可變的對象。而NSArray對象調用mutableCopy方法時,mutableCopy方法會調用- (id)mutableCopyWithZone:(NSZone *)zone,獲得可變的對象。
因此,若是自定義類具備可變和不可變的區別,想讓它支持拷貝時,就須要同時實現NSCopying和NSMutableCopying,在- (id)copyWithZone:(NSZone *)zone返回的是不可變對象,在- (id)mutableCopyWithZone:(NSZone *)zone返回的是可變對象。
@property (nonatomic, copy) NSString *string;
對於NSString , NSArray,NSDictionary ,要使用copy關鍵字。
由於其子類存在mutable 版本,使用strong,指向的是同一個地址,其值若是改動,都會改動。
舉例:
@property (nonatomic, strong) NSString *string;
NSMutableString *string = [NSMutableString stringWithString:@"哇"];
self.string = string;
[string appendString:@"哈哈"];
NSLog(@"%@",self.string);
淺拷貝和深拷貝
深拷貝:在拷貝對象自身時,將其底層數據也一併複製過去
Foundation框架中的全部collection類在默認狀況下都執行淺拷貝,也就是說,只拷貝容器對象自己,而不復制其中數據。
淺拷貝以後的內容和原始內容均指向相同對象。
而深拷貝以後的內容所指的對象是原始內容中相關對象的一份拷貝。
想要實現深拷貝,像數組,字典,集合 要實現下面這些方法。