话不多说先上代码
分别copy和strong修饰可变和不可变的字符串
@property (nonatomic,copy) NSString *str_copy;
@property (nonatomic,strong) NSString *str_strong;
@property (nonatomic,strong) NSMutableString *mustr_strong;
@property (nonatomic,copy) NSMutableString *mustr_copy;
//打印方法
-(void)printStrandAdd{
NSLog(@"_str_copy: %p :%@",_str_copy,_str_copy);
NSLog(@"_str_strong: %p :%@",_str_strong,_str_strong);
NSLog(@"_mustr_copy: %p :%@",_mustr_copy,_mustr_copy);
NSLog(@"_mustr_strong: %p :%@",_mustr_strong,_mustr_strong);
}
以可变字符串为源
-(void)MutabStr{
NSMutableString *string = [[NSMutableString alloc]initWithString:@"123456789000"];
self.str_copy = string;
self.str_strong = string;
self.mustr_strong = string;
self.mustr_copy = string;
// [mustr_copy appendString:@"qwertyuiosdfghj"] 会崩溃
NSLog(@"string源: %p :%@",string,string);
[self printStrandAdd];
NSLog((@"____________修改源________________"));
[string appendString:@"qwertyuiosdfghj"];
NSLog(@"string源: %p :%@",string,string);
[self printStrandAdd];
}
运行结果
2020-01-09 15:26:18.052008+0800 testCI[7652:4203196] ==========Mutab==============
2020-01-09 15:26:18.052140+0800 testCI[7652:4203196] string源: 0x28181bdb0 :123456789000
2020-01-09 15:26:18.052628+0800 testCI[7652:4203196] _str_copy: 0x281658940 :123456789000
2020-01-09 15:26:18.052684+0800 testCI[7652:4203196] _str_strong: 0x28181bdb0 :123456789000
2020-01-09 15:26:18.052730+0800 testCI[7652:4203196] _mustr_copy: 0x281658760 :123456789000
2020-01-09 15:26:18.052761+0800 testCI[7652:4203196] _mustr_strong: 0x28181bdb0 :123456789000
2020-01-09 15:26:18.052858+0800 testCI[7652:4203196] ____________修改源________________
2020-01-09 15:26:18.053029+0800 testCI[7652:4203196] string源: 0x28181bdb0 :123456789000qwertyuiosdfghj
2020-01-09 15:26:18.053294+0800 testCI[7652:4203196] _str_copy: 0x281658940 :123456789000
2020-01-09 15:26:18.053331+0800 testCI[7652:4203196] _str_strong: 0x28181bdb0 :123456789000qwertyuiosdfghj
2020-01-09 15:26:18.053365+0800 testCI[7652:4203196] _mustr_copy: 0x281658760 :123456789000
2020-01-09 15:26:18.053610+0800 testCI[7652:4203196] _mustr_strong: 0x28181bdb0 :123456789000qwertyuiosdfghj
可见对于可变的源字符串,修改内容时候,指针地址不会改变为原地址。str_copy、self.mustr_copy 赋值之后重新生成了一块地址,是深复制。经过copy修饰过的可变字符串,变为不可变,若是[mustr_copy appendString:@"qwertyuiosdfghj"] 会崩溃
以不可变字符串为源
-(void)stringNomauta{
NSString *string = [NSString stringWithFormat:@"123456789000"];
self.str_copy = string;
self.str_strong = string;
self.mustr_strong = string;
self.mustr_copy = string;
NSLog(@"string源: %p :%@",string,string);
[self printStrandAdd];
NSLog(@"____________修改源________________");
string = [NSString stringWithFormat:@"qwertyuiosdfghj"];
NSLog(@"string源: %p :%@",string,string);
[self printStrandAdd];
}
运行结果
2020-01-09 15:26:18.048870+0800 testCI[7652:4203196] ==========NoMutab==============
2020-01-09 15:26:18.049020+0800 testCI[7652:4203196] string源: 0x28164ffe0 :123456789000
2020-01-09 15:26:18.049061+0800 testCI[7652:4203196] _str_copy: 0x28164ffe0 :123456789000
2020-01-09 15:26:18.049101+0800 testCI[7652:4203196] _str_strong: 0x28164ffe0 :123456789000
2020-01-09 15:26:18.049135+0800 testCI[7652:4203196] _mustr_copy: 0x28164ffe0 :123456789000
2020-01-09 15:26:18.049168+0800 testCI[7652:4203196] _mustr_strong: 0x28164ffe0 :123456789000
2020-01-09 15:26:18.049204+0800 testCI[7652:4203196] ____________修改源________________
2020-01-09 15:26:18.049294+0800 testCI[7652:4203196] string源: 0x28187a0a0 :qwertyuiosdfghj
2020-01-09 15:26:18.049496+0800 testCI[7652:4203196] _str_copy: 0x28164ffe0 :123456789000
2020-01-09 15:26:18.049646+0800 testCI[7652:4203196] _str_strong: 0x28164ffe0 :123456789000
2020-01-09 15:26:18.049775+0800 testCI[7652:4203196] _mustr_copy: 0x28164ffe0 :123456789000
2020-01-09 15:26:18.051861+0800 testCI[7652:4203196] _mustr_strong: 0x28164ffe0 :123456789000
可见对于不可变的源字符串,无论copy还是strong,都是浅复制,仅复制指针。NSString 修改内容时,会开辟一块新的内存,有新的指针。而愿地址被 str_copy 、self.str_strong、 self.mustr_strong 、self.mustr_copy 指向原地址不会改变。
拓展
不管是集合类对象(NSArray、NSDictionary、NSSet ... 之类的对象),还是非集合类对象(NSString, NSNumber ... 之类的对象),接收到copy和mutableCopy消息时,都遵循以下准则:
- 1.copy 返回的是不可变对象(immutableObject);如果用copy返回值调用mutable对象的方法就会crash。
- 2.mutableCopy 返回的是可变对象(mutableObject)
网友评论