iOS的深浅拷贝
2020-01-06 本文已影响0人
红色海_
浅拷贝:指针拷贝,引用拷贝,指向同一内存地址
深拷贝:内容拷贝,指向不同内存地址,但内容相同
1、copy和mutableCopy只能作单层拷贝,针对容器类仅仅使用一次拷贝操作时,只能产生新的容器,但是元素共用一份
2、如果想要拷贝元素,则需要调用系统方法copyItems,将元素copy一份(这个元素copy也仅仅是单层拷贝)
3、如果是容器嵌套容器时,单单使用一次copy或者mutableCopy,严格意义上来说,是无法做到深拷贝的,
因为元素可能没有被拷贝,并且如果元素是不可变类型时,无论怎么样做都只能是引用拷贝,因为最小元素是不可变的,仅仅有一份内存地址
4、因此非容器类,如NSString,NSMutableString等,copy和mutableCopy作单层拷贝就达到了最终效果
验证1:非容器类,不可变类型
NSString *string = @"ABCDEFG";
NSString *string_copy = string.copy;
NSMutableString *string_mutableCopy = string.mutableCopy;
NSLog(@"string 地址:%p",string);
NSLog(@"string_copy 地址:%p",string_copy);
NSLog(@"string_mutableCopy地址:%p",string_mutableCopy);
[string_mutableCopy appendString:@"-test"];
NSLog(@"原始字符串: %@",string);
NSLog(@"string_copy字符串: %@",string_copy);
NSLog(@"string_mutableCopy字符串:%@",string_mutableCopy);
-----------------------------------------------
输出结果:
string 地址:0x12345678
string_copy 地址:0x12345678
string_mutableCopy地址:0x12345600
原始字符串: ABCDEFG
string_copy字符串: ABCDEFG
string_mutableCopy字符串:ABCDEFG-test
-----------------------------------------------
#######结论: copy为浅拷贝, mutableCopy为深拷贝
验证2:非容器类,可变类型
NSString *string = [NSMutableString stringWithString:@"BBBBB"];
NSString *string_copy = string.copy;
NSMutableString *string_mutableCopy = string.mutableCopy;
NSLog(@"string地址: %p",string);
NSLog(@"string_copy地址: %p",string_copy);
NSLog(@"string_mutableCopy地址:%p",string_mutableCopy);
[string_mutableCopy appendString:@"-test"];
NSLog(@"原始字符串: %@",string);
NSLog(@"string_copy字符串: %@",string_copy);
NSLog(@"string_mutableCopy字符串:%@",string_mutableCopy);
-----------------------
输出结果:
string 地址:0x12345678
string_copy 地址:0x66612345
string_mutableCopy地址:0x12345600
原始字符串: BBBBB
string_copy字符串: BBBBB
string_mutableCopy字符串:BBBBB-test
-----------------------
######结论:copy为深拷贝, mutableCopy为深拷贝
验证3:容器类(单层),不可变类型, 元素不可变非容器,单次拷贝
NSArray *items = @[@"My apple",@"Your pear"];
NSArray *items_copy = items.copy;
NSMutableArray *items_mutableCopy = items.mutableCopy;
NSLog(@"items地址: %p",items);
NSLog(@"items_copy地址: %p",items_copy);
NSLog(@"items_mutableCopy地址:%p",items_mutableCopy);
for (NSString *itemStr in items) {
NSLog(@"items不可变元素地址: %p",itemStr);
}
for (NSString *itemStr in items_copy) {
NSLog(@"items_copy不可变元素地址: %p",itemStr);
}
for (NSString *itemStr in items_mutableCopy) {
NSLog(@"items_mutableCopy不可变元素地址:%p",itemStr);
}
-----------------------
输出结果:
items 地址:0x12345678
items_copy 地址:0x12345678
items_mutableCopy地址:0x12345600
items不可变元素地址: 0x12345620
items不可变元素地址: 0x12345621
items_copy不可变元素地址: 0x12345620
items_copy不可变元素地址: 0x12345621
items_mutableCopy不可变元素地址:0x12345620
items_mutableCopy不可变元素地址:0x12345621
-----------------------
######结论:copy不产生新容器,mutableCopy产生新容器,但是最小元素内存地址都一样,浅拷贝
验证4:容器类(单层),不可变类型,元素不可变非容器,元素拷贝
// 更改
NSArray *items_copy = [[NSArray alloc] initWithArray:items copyItems:YES];
NSMutableArray *items_mutableCopy = [[NSMutableArray alloc] initWithArray:items copyItems:YES];
######结论:产生新容器,但是最小元素内存地址都一样,浅拷贝
验证5: 容器类(单层),不可变类型,元素可变非容器,单次拷贝
NSMutableString *string1 = [NSMutableString stringWithString:@"apple"];
NSMutableString *string2 = [NSMutableString stringWithString:@"pear"];
NSArray *items = @[string1,string2];
NSArray *items_copy = items.copy;
NSMutableArray *items_mutableCopy = items.mutableCopy;
######结论:copy不产生新容器,mutableCopy产生新容器,但是最小元素内存地址都一样,浅拷贝
验证6: 容器类(单层),不可变类型,元素可变非容器,元素拷贝
NSArray *items_copy = [[NSArray alloc] initWithArray:items copyItems:YES];
NSMutableArray *items_mutableCopy = [[NSMutableArray alloc] initWithArray:items copyItems:YES];
######结论:产生新容器,最小元素内存地址不一样,深拷贝
验证7:容器类(单层),可变类型,元素不可变非容器,单次拷贝
NSMutableArray *items = [NSMutableArray arrayWithArray:@[@"apple",@"pear"]];
NSArray *items_copy = items.copy;
NSMutableArray *items_mutableCopy = items.mutableCopy;
######结论:copy、mutableCopy都产生新容器,但是最小元素内存地址都一样,浅拷贝
验证8:容器类(单层),可变类型,元素不可变,元素拷贝
NSMutableArray *items = [NSMutableArray arrayWithArray:@[@"apple",@"pear"]];
NSArray *items_copy = [[NSArray alloc] initWithArray:items copyItems:YES];
NSMutableArray *items_mutableCopy = [[NSMutableArray alloc] initWithArray:items copyItems:YES];
######结论:copy、mutableCopy都产生新容器,但是最小元素内存地址都一样,浅拷贝
验证9:容器类(单层),可变类型,元素可变,单次拷贝
NSMutableString *string1 = [NSMutableString stringWithString:@"apple"];
NSMutableString *string2 = [NSMutableString stringWithString:@"pear"];
NSMutableArray *items = [NSMutableArray arrayWithArray:@[string1,string2]];
NSArray *items_copy = items.copy;
NSMutableArray *items_mutableCopy = items.mutableCopy;
######结论:copy、mutableCopy都产生新容器,但是最小元素内存地址都一样,浅拷贝
验证10:容器类(单层),可变类型,元素可变,元素拷贝
NSArray *items_copy = [[NSArray alloc] initWithArray:items copyItems:YES];
NSMutableArray *items_mutableCopy = [[NSMutableArray alloc] initWithArray:items copyItems:YES];
######结论:产生新容器,最小元素内存地址不一样,深拷贝
验证11:容器类(多层,嵌套容器)
略
结论:
1、容器类是否可以深拷贝,首先要看最小元素,若最小元素为不可变类型,容器类的任何拷贝操作都是浅拷贝
2、如使用copyItems函数,并且元素为可变类型时,可以连元素一起拷贝,属于深拷贝(元素非容器)