Copy与MutableCopy的使用

首先,明白复制的原则:

  • 复制出一个新的对象
  • 对原来对象或新复制出的对象进行修改不会互相影响

然后,明白CopyMutableCopy的原则

  • 使用Copy出来的对象都是不可变对象
  • 使用MutableCopy出来的对象都是可变对象

NSString使用Copy

 NSString *oldString = [NSString stringWithFormat:@"haha"];
 NSString *newString = [oldString copy];
    
NSLog(@"oldString:%p---newString:%p",oldString,newString);

//打印结果
oldString:0xa000000616861684---newString:0xa000000616861684

结论:对不可变对象使用Copy不产生新对象,只会进行指针拷贝,即浅拷贝,因为都是不可变对象,不存在修改之后互相影响的情况,所以系统为节约内存,只进行了指针拷贝.

NSMutableString使用Copy

NSMutableString *oldString = [NSMutableString stringWithFormat:@"haha"];
NSString *newString = [oldString copy];
    
[oldString appendString:@"change"];
    
NSLog(@"oldString:%@---newString:%@",oldString,newString);
NSLog(@"oldString:%p---newString:%p",oldString,newString);

//打印结果
oldString:hahachange---newString:haha
oldString:0x60800027ef80---newString:0xa000000616861684

结论:对可变对象使用Copy会产生新的对象,新对象为不可变对象,对新对象或原对象修改不会互相影响

NSString使用MutableCopy

NSString *oldString = [NSString stringWithFormat:@"haha"];
    NSMutableString *newString = [oldString mutableCopy];
    
    [newString appendString:@"change"];
    
    NSLog(@"oldString:%@---newString:%@",oldString,newString);
    NSLog(@"oldString:%p---newString:%p",oldString,newString);

//打印结果
oldString:haha---newString:hahachange
oldString:0xa000000616861684---newString:0x6000002688c0

结论:对不可变对象使用MutableCopy会产生新的对象,新对象为可变对象,对新对象或原对象修改不会互相影响

NSMutableString使用MutableCopy

 NSMutableString *oldString = [NSMutableString stringWithFormat:@"haha"];
    NSMutableString *newString = [oldString mutableCopy];
    
    [newString appendString:@"change"];
    
    NSLog(@"oldString:%@---newString:%@",oldString,newString);
    NSLog(@"oldString:%p---newString:%p",oldString,newString);

//打印结果
oldString:haha---newString:hahachange
oldString:0x600000261240---newString:0x600000262300

结论:对可变对象使用MutableCopy会产生新的对象,新对象为可变对象,对新对象或原对象修改不会互相影响

@property中的copy使用

在普通的strong修饰的属性生成的set方法实现为简单赋值,即:

@property (nonatomic, strong) NSString *name;

- (void)setName:(NSString *)name{
    _name = name;
}

而使用copy修饰的属性生成的set方法则是把传入对象拷贝一份内存赋值给成员变量,即:

@property (nonatomic, strong) NSString *name;

- (void)setName:(NSString *)name{
    _name = [name copy];
}

结论:这样我们就可以达到对赋值前后的对象之间修改不会互相影响

但是这样的话就会出现一种特殊情况,当成员变量是可变类型的时候,通过copy出来的是不可变对象,赋值给成员变量后其本质上已经为不可变对象,然后我们仍会误以为其实可变对象,而调用一些可变对象的方法,此时程序会崩溃:

@property (nonatomic, copy) NSMutableString *mutableString;

self.mutableString = [NSMutableString stringWithFormat:@"test"];
    
//这里`_mutableString`已经是不可变字符串了,使用`appendString `方法会崩溃
[self.mutableString appendString:@"test"];

//错误提示:
-[NSTaggedPointerString appendString:]: unrecognized selector sent to instance 0xa000000747365744

结论:我们要避免对可变对象使用copy

你可能感兴趣的:(Copy与MutableCopy的使用)