深拷贝与浅拷贝;copy与mutableCopy;容器类型的深拷贝;copy和strong;

一、分成三组对比NSMutableDictionary与NSDictionary;NSMutableString与NSString;NSMutableArray与NSArray分别调用copy和mutableCopy方法,查看对应的对象的地址值判断深浅拷贝;

 

1、字典:(示例代码 testDics方法,有四种组合)

self.mutableDic是NSMutableDictionary类型:

NSMutableDictionary *newMutDic = [self.mutableDic mutableCopy];//深

NSDictionary *newDic = [self.mutableDic copy];//深

self.dic是NSDictionary类型:

NSMutableDictionary *newMutDic = [self.dic mutableCopy];//深

NSDictionary *newDic = [self.dic copy];//浅

 

2、字符串:(示例代码 testStrings方法,有四种组合)

self.mutableStr是NSMutableString类型:

 NSMutableString *newMutStr = [self.mutableStr mutableCopy];//深

NSString *newStr = [self.mutableStr copy];//深

self.str是NSString类型:

NSMutableString *newMutStr = [self.str mutableCopy];//深

NSString *newStr = [self.str copy];//浅

 

3、数组:(示例代码 testArrays方法,有四种组合)

self.mutableArray是NSMutableArray类型:

  NSMutableArray *newMutArray = [self.mutableArray mutableCopy];//深

  NSArray *newArray = [self.mutableArray copy];//深

self.array是NSArray类型:

  NSMutableArray *newMutArray = [self.array mutableCopy];//深

  NSArray *newArray = [self.array copy];//浅

 

结论:根据以上1、2、3的代码可知,只有NS类型调用copy方法才是浅拷贝,其他的情况全是深拷贝

 

二、容器类型的实例的深拷贝:(示例代码testMutableArrayArray方法)

此处以数组为例,只有在上边一是数组深拷贝的情况下为例:

NSMutableArray *newMuArrayArray = [self.mutableArrayArray mutableCopy];

[newMuArrayArray addObject:@[@"44",@"33"]];

[self.adArray addObject:@"3"];

NSArray *ss = newMuArrayArray[0];

 NSLog(@"%@ %p == %@ %p  == %@  %p  == %@  %p",self.mutableArrayArray,self.mutableArrayArray,newMuArrayArray,newMuArrayArray,self.adArray,self.adArray,ss,ss);

上述打印:self.adArray与ss的地址值相同;self.mutableArrayArray与newMuArrayArray地址值不同

结论:容器类(此处以数组为例)调用copy或mutableCopy能出现的深拷贝的情况下,只是容器的深拷贝,而非容器内元素的深拷贝

 

三、用copy还是strong:(示例代码testStrongAndCopyStr方法)

如果你已经完全理解了上述一,这里就非常好理解了:

声明属性为NSString:

@property (nonatomic,strong) NSString *strongString;

@property (nonatomic,copy) NSString *copString;

为属性赋值:

NSMutableString *oriMuStr = [[NSMutableString alloc] initWithString:@"muStr原始的muStr"];

    self.strongString = oriMuStr;

    self.copString = oriMuStr;

改变oriMuStr的值:

NSRange r = {3,2};

    [oriMuStr replaceCharactersInRange:r withString:@"ooo"];

打log:NSLog(@"\n%@ %@ %@",self.strongString,self.copString,oriMuStr);

属性为NSString类型时,self.copString没有随着oriMuStr的改变而改变,而self.strongString变了。

同理,当属性为NSMutableString类型时:

声明属性:

@property (nonatomic,strong) NSMutableString *strongMutaString;

@property (nonatomic,copy) NSMutableString *copMutaString;

 

NSMutableString *oriMuStr = [[NSMutableString alloc] initWithString:@"muStr原始的muStr"];

    self.strongMutaString = oriMuStr;

    self.copMutaString = oriMuStr;

    NSRange r = {3,2};

    [oriMuStr replaceCharactersInRange:r withString:@"ooo"];

    NSLog(@"\n%@ %@ %@",self.strongMutaString,self.copMutaString,oriMuStr);

属性为NSMutableString类型时,self.copMutaString没有随着oriMuStr的改变而改变,而self.strongMutaString变了。

综上,结论:

无论是声明NSString还是NSMutableString类型的属性时,我们希望此属性被赋值为NSMutableString类型的字符串后,此属性不会因这个可变类型字符串的改变而改变(这也是多数情况下的用法),那就用copy修饰属性

同理、其他相关类型亦是如此。

解析:声明属性时用copy和strong其实是重写了属性的set方法

例如属性声明为copy时的copString属性的set方法如下:

-(void)setCopString:(NSString *)copString{

    _copString = [copString copy];//重写set方法时,调用copy后,即使声明属性时不用copy关键字(用strong,strong是默认的,所以重写set方法不加strong也默认是strong的)也有copy的作用

}

当NSString属性的指针指向NSSMutableString时,其set方法是NSSMutableString的copy根据一中关于string类型的分析可知,此时是深拷贝,故不希望NSString类型的属性在使用时发生不想要的改变的话,需要copy修饰

示例代码:https://download.csdn.net/download/denggun12345/10768386

 

你可能感兴趣的:(移动)