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函数,并且元素为可变类型时,可以连元素一起拷贝,属于深拷贝(元素非容器)

上一篇 下一篇

猜你喜欢

热点阅读