内存管理:Copy

Copy的目的

copy的目的,是希望能产生一个同样的副本。希望修改副本的时候,不会影响到原来的数据。修改原来的数据时,也不影响副本数据

copy 与mutableCopy

1.copy 产生一个不可变的副本
2.mutbaleCopy 产生一个可变的副本

NSString *str = [NSString stringWithFormat:@"test"];
    NSString *str2 = [str copy];
    NSMutableString *str3 = [str mutableCopy];
    [str3 appendString:@"123"];
    NSLog(@"%@,%@,%@",str,str2,str3);
打印结果为:test,test,test123
//如果将str2改为NSMutableString 进行 mutableCopy操作的话,程序会崩溃
报 unrecognized selector sent to instance 方法找不到的错误
image.png

深拷贝与浅拷贝

深拷贝:内容copy,产生一个新的对象(内存地址不同)
浅拷贝:指针copy,不会产生新的对象(具有相同的内存地址)

为什么会形成深拷贝与浅拷贝呢?

因为 iOS 中,字符串、数组、字典具有可变类型和不可变类型

NSString 不可变字符串,不可以修改
NSMutableString 可变字符串 ,可以修改字符串,如拼接新内容进去
NSArray 、NSMutableArray 同理
NSDictionary、NSMutableDictionary 同理

当对一个不可变字符串进行copy 的时候,它本身就不可以改变,所以,没有必要开辟一个新的内存空间去存储相同的内容。所以只需要copy它的内存地址赋给变量即可--浅拷贝
当对一个不可变字符串进行mutableCopy 的时候,需要参数一个可变字符串,那么就没办法继续使用同一个内存地址,所以,需要开辟一个新的内存空间,存储新的对象,以此保证新字符串改变的时候,不会影响到之前的字符串


image.png

NSString为什么使用copy修饰

Strong关键字是一个浅拷贝,仅仅是引用对象的地址,不会产生新的对象

    Person *p = [[Person alloc] init]; 
    p.name = @"123";
    NSMutableString *str = [NSMutableString stringWithString:@"abc"];
    p.name = str;
    [str appendString:@"xxx"];
    NSLog(@" p.name = %@",p.name);

当Person的name属性使用strong修饰的时候,如果我们将一个可变的字符串赋值给name 的时候,那么name 的地址指向的就是一个可变字符串的地址。
当我们在其他地方修改可变字符串 str 的时候,name 的值也会被修改。那么就存在了一个隐患,属性name可能会在某一个地方被串改,而我们却不知道

如果使用copy 修饰的话,那么属性name 就变成了一个不可变的字符串,会产生一个新的不可变的对象,内容与str一致,并且不可以被修改,同时保证了数据的安全性

你可能感兴趣的:(内存管理:Copy)