copy和strong修饰字段的区别

话不多说先上代码

分别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)

你可能感兴趣的:(copy和strong修饰字段的区别)