實現拷貝,需要遵守以下兩個協議
拷貝返回對象的種類
拷貝的種類
注意
copy
retain
非容器對象(如NSString
))
對于不可變對象
規則
示例
- (void)imutableInstanceCopy{ NSString *string = @"Welcome to Xcode"; //copy,淺拷貝 NSString *stringCopy = [string copy]; //mutableCopy,返回的對象可變 NSMutableString *stringMutableCopy = [string mutableCopy]; [stringMutableCopy appendString:@"!"]; //string與stringCopy的內存地址相同 NSLog(@"string: %p", string); NSLog(@"strongCopy: %p", stringCopy); //string與stringMutableCopy的內存地址不同,分配了新的內存 NSLog(@"stringMCopy:%p", stringMutableCopy);}
對于可變對象
規則
示例
- (void)mutableInstanceCopy{ NSMutableString *mutableString = [NSMutableString stringWithString: @"Welcome to Xcode"]; //深拷貝,返回對象不可變 NSString *stringCopy = [mutableString copy]; NSMutableString *mutableStringCopy = [mutableString copy]; //運行時,此句會報錯,錯誤信息“Attempt to mutate immutable object with appendString:” [mutableStringCopy appendString:@"~~~"]; //深拷貝,返回對象可變 NSMutableString *stringMutableCopy = [mutableString mutableCopy]; [stringMutableCopy appendString:@"!"]; //三者與mutableString的內存地址都不同 NSLog(@"mutableString: %p", mutableString); NSLog(@"string: %p", stringCopy); NSLog(@"mutableStringCopy: %p", mutableStringCopy); NSLog(@"stringMutbleCopy:%p", stringMutableCopy);}
容器對象(NSArray
)
注意
示例
- (void)containerInstanceShallowCopy{ NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"Welcome"],@"to",@"Xcode",nil]; //淺拷貝 NSArray *arrayCopy = [array copy]; //深拷貝 NSMutableArray *arrayMutableCopy = [array mutableCopy]; NSLog(@"array: %p", array); NSLog(@"arrayCopy: %p", arrayCopy); NSLog(@"arrayMutableCopy: %p", arrayMutableCopy); //容器內的對象是淺拷貝,即它們在內存中只有一份 NSMutableString *testString = [array objectAtIndex:0]; [testString appendString:@" you"]; //三個數組的內容同時改變 NSLog(@"array[0]: %@", array[0]); NSLog(@"arrayCopy[0]: %@", arrayCopy[0]); NSLog(@"arrayMutableCopy[0]: %@", arrayMutableCopy[0]);}
實現真正意義上的深復制
- (void)containerInstanceDeepCopy{ NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"Welcome"],@"to",@"Xcode",nil]; //數組內對象是指針復制 NSArray *deepCopyArray = [[NSArray alloc] initWithArray:array]; //真正以上的深復制,數組內對象是對象復制 NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:array]]; NSLog(@"array: %p", array); NSLog(@"deepCopyArray: %p", deepCopyArray); NSLog(@"trueDeepCopyArray: %p", trueDeepCopyArray); //改變array的第一個元素 [[array objectAtIndex:0] appendString:@" you"]; //只影響deepCopyArray數組的第一個元素 NSLog(@"array[0]: %@", array[0]); NSLog(@"arrayCopy[0]: %@", deepCopyArray[0]); //不影響trueDeepCopyArray數組的第一個元素,是真正意義上的深拷貝 NSLog(@"arrayMutableCopy[0]: %@", trueDeepCopyArray[0]);}
自定義對象
在定義對象要實現拷貝,需要遵守NSCoping與NSMutableCoping協議,并實現以下方法
示例(自定對象Person的拷貝)
遵守協議,設置成員屬性
@interface Person : NSObject <NSCopying, NSMutableCopying>/**姓名*/@PRoperty (nonatomic, copy) NSMutableString *name;/**地址*/@property (nonatomic, copy) NSString *address;/**年齡*/@property (nonatomic, assign) NSInteger age;@end
重寫初始化方法
- (instancetype)init{ if (self = [super init]) { self.name = [[NSMutableString alloc] initWithString:@"XiaoYaowang"]; self.address = @"世俗孤島"; self.age = 3; } return self;}
實現- (id)copyWithZone:(NSZone *)zone
- (id)copyWithZone:(NSZone *)zone{ Person *p = [[[self class] allocWithZone:zone] init]; p.name = [self.name copy]; p.address = [self.address copy]; p.age = self.age; return p;}
實現- (id)mutableCopyWithZone:(NSZone *)zone
- (id)mutableCopyWithZone:(NSZone *)zone{ Person *p = [[[self class] allocWithZone:zone] init]; //注意,此處是mutableCopy方法 p.name = [self.name mutableCopy]; p.address = [self.address copy]; p.age = self.age; return p;}
新聞熱點
疑難解答