string/ array /dictinary正确使用方式

字符串可以用strong修饰?

开发中,我们经常遇见属性变量修饰问题(string,array,dictionary),有的修饰字符串用copy,有的却是用strong。那今天我们就以字符串做为例子把这个问题说透,数组和字典同理。


我们先看看一个字符串在内存中对象和指针的地址到底是怎么变化的。
NSMutableString *string = [NSMutableString stringWithFormat:@"abc"];
    NSLog(@"%p - %p",string,&string);
    
    [string appendString:@"123"];
    NSLog(@"%p - %p",string,&string);
    
    string = [NSMutableString stringWithFormat:@"123"];
      NSLog(@"%p - %p",string,&string);

打印结果:
0x6000008f9770 - 0x7ffee3558a48 
0x6000008f9770 - 0x7ffee3558a48
0x6000008f99e0 - 0x7ffee3558a48
可以看出可变字符串对字符串增加 、删除 对象地址和 指针地址都是不改变的。而对字符串修改值的情况是对象的地址会改变,指针的地址不变。 

有了上面的字符串的理解,那我们给一个对象赋值又会怎么样呢?下面我们分别以一个可变字符串和一个不可变字符串来分别对copy修饰的属性和strong修饰的属性做如下操作:

@property(nonatomic,strong)NSString *str1;
@property(nonatomic,copy)NSString *str2;

NSMutableString *string = [NSMutableString stringWithFormat:@"abc"];
self.str1 = string;
self.str2 = string;
 NSLog(@"origin : %p - %p - %@",string,&string,string);
 NSLog(@"str1 : %p - %p - %@",self.str1,&_str1,self.str1);
 NSLog(@"str2 : %p - %p - %@",self.str2,&_str2,self.str2);
打印结果:
 origin : 0x6000007448a0 - 0x7ffee543ca48 - abc
 str1 : 0x6000007448a0 - 0x7fb54d40d6d0 - abc
 str2 : 0xa6e53c7d209f903b - 0x7fb54d40d6d8 - abc

 修改可变字符后
   [string appendString:@"123"];
    NSLog(@"origin : %p - %p - %@",string,&string,string);
    NSLog(@"str1 : %p - %p - %@",self.str1,&_str1,self.str1);
    NSLog(@"str2 : %p - %p - %@",self.str2,&_str2,self.str2);
 打印结果:
  origin : 0x6000023c51d0 - 0x7ffee431ea48 - abc123
  str1 : 0x6000023c51d0 - 0x7fc5ccc0d0a0 - abc123
  str2 : 0x972d53aa8f482d3f - 0x7fc5ccc0d0a8 - abc

8B98E5E8-0250-4B8C-B5B1-741390B38D4C.png

下面我们用不可变字符串操作

   NSString *string = [NSString stringWithFormat:@"abc"];
    self.str1 = string;
    self.str2 = string;
    NSLog(@"origin : %p - %p - %@",string,&string,string);
    NSLog(@"str1 : %p - %p - %@",self.str1,&_str1,self.str1);
    NSLog(@"str2 : %p - %p - %@",self.str2,&_str2,self.str2);

结果如下:
origin : 0xf2a100067c5c5d9b - 0x7ffee243da48 - abc
  str1 : 0xf2a100067c5c5d9b - 0x7fc2a0d08910 - abc
  str2 : 0xf2a100067c5c5d9b - 0x7fc2a0d08918 - abc
9CE45A12-F6C9-4F10-A2DC-3142667EAC4E.png

由以上就可以看出来了,开发中如果遇见属性字符串用strong修饰,在将可变字符串赋值的情况,就可能改变了可变字符串,同时也改变了用strong修饰的字符串值,根本原因就是这2个字符串指针(地址不同)但是却指向了同一片内存区域。
为了避免这种情况发生,开发中尽量对不可变的字符、数组、字典用copy修饰,可变的则用strong修饰。

你可能感兴趣的:(string/ array /dictinary正确使用方式)