在iOS开发中定义属性是经常要做的 这里呢 对于字符串来讲有点特殊 可能你已经写顺手了 在定义一个字符串的属性时 随手就这样写@property (nonatomic, strong) NSString *str; 哈哈 是不是 反正我写的挺习惯 哈哈 那么为啥 为啥这个字符串就要用copy呢 这里面有些学问
首先从字面上理解一下 copy 拷贝的意思 在iOS开发中copy包含两个意思(深拷贝, 浅拷贝)
深拷贝: 就是指新开辟一块内存 将拷贝的内容放到这快新开辟的内存
实现(三种):
NSString *str = @"nan";
NSMutableString *str1 = [[NSMutableString alloc] init];
str1.string = @"hard";
NSString *str2 = [str1 copy];
NSString *str3 = [str1 mutableCopy];
NSString *str4 = [str mutableCopy];
NSLog(@"%@--------------------%p", str, str);
NSLog(@"%@--------------------%p", str1, str1);
NSLog(@"%@--------------------%p", str2, str2);
NSLog(@"%@--------------------%p", str3, str3);
NSLog(@"%@--------------------%p", str4, str4);
D14A3400-AE51-4EE3-88CA-E77EE10C1204.png
大家看一下上面的打印地址 会发现上面的这几种copy后的地址都不一样 内容是一样的 我们成这种拷贝为深拷贝(深拷贝后 是开辟了一块新的内存 然后将内容复制到这块内存中)
总结一下 深拷贝一共可分3种形式:
- 对可变的string 进行copy
- 对可变的string 进行mutableCopy
- 对不可变的string 进行mutableCopy
浅拷贝: 拷贝的是指针 生成了另一个指针 页指向之前那块内存
NSString *str = @"yes";
NSString *str1 = [str copy];
NSLog(@"%@----------------%p", str, str);
NSLog(@"%@----------------%p", str1, str1);
A80FCE63-7BC6-4308-A751-DE3934BE72C6.png
细心的你会发现这里的str和str1的地址是一样的 所以说 浅拷贝之拷贝了指针 这是生成了两个指针并且指向同一块内存
那么 为什么在定义字符串属性时候就要用copy呢 我用strong不行吗(不行 哈哈) 下面我们来举例说明一下这个问题哈
// 定义一个strong修饰的字符串
@property (nonatomic, strong) NSString *nameStr;
// 创建一个不可变字符串给nameStr赋值
NSString *str = @"好的";
self.nameStr = str;
// 再改变str的值
str = @"一点不好";
NSLog(@"%@, %@", str, self.nameStr);
C5C315DB-1A93-49A4-B28C-48D2F0281CF3.png
从输出的结果来看 str值的改变并没有影响到nameStr的值
接下来我们再来看一个例子
@property (nonatomic, strong) NSString *nameStr;
// 创建一个可变的字符串来给nameStr赋值
NSMutableString *str = [NSMutableString stringWithFormat:@"好的"];
self.nameStr = str;
str.string = @"一点不好";
NSLog(@"%@, %@", str, self.nameStr);
0434F20B-931A-4C9C-901F-7E22F939B89C.png
从输出结果你就可以清楚的看出 在使用可变字符串给strong修饰的字符串赋值时 改变这个可变字符串值得时候 nameStr也相应的改变 你可能并不希望这个nameStr随着那个可变的字符串改变 这时候就会出现一些不好的情况
但是你如果用copy来修饰字符串 就不会出现这个问题 用copy主要就是放置NSString被随意修改 如果NSString的赋值来源是NSString那么用copy和strong的效果是一样的 但是如果NSString的赋值来源是NSMutableString 用strong的话就会使NSString的值发生改变 这时用copy是深拷贝 生成一个新的对象 在改变NSMtableString的时候就不会影响到 NSString
总的来说 使用copy来修饰字符串 就是为了不影响可变字符串给字符串赋值时 产生的不良结果
网友评论