字符串修饰符strong和copy的区别

1.定义两个属性

@property (nonatomic, strong) NSString  *stringStrong;
@property (nonatomic, copy)   NSString  *stringCopy;

情况1:
分别给这两个属性赋值NSString类型

    - (void)testStrongAndCopyStr{

    //情况1:给属性赋NSString类型的值

    NSString *strongStr = @"aa";
    NSString *copyStr = @"bb";
    self.stringStrong = strongStr;
    self.stringCopy = copyStr;

    //strongStr是一个指针变量,它指向strongStr对象的地址。&strongStr指的是strongStr这个指针变量所在的地址。
     ZWWLog(@"strongStr地址==%p; self.stringStrong地址==%p",strongStr,self.stringStrong);
    ZWWLog(@"copyStr地址==%p; self.stringCopy地址==%p",copyStr,self.stringCopy);

     NSString *strong1Append =  [strongStr stringByAppendingString:@"+11111"];
    NSString *copy1Append = [copyStr stringByAppendingString:@"+22222"];
    ZWWLog(@"原字符串拼接后strong1Append地址==%p,strong1Append内容==%@,strongStr地址==%p,内容==%@, self.stringStrong地址==%p,内容==%@",strong1Append,strong1Append, strongStr,strongStr,self.stringStrong,self.stringStrong);
    ZWWLog(@"原字符串拼接后copy1Append地址=%p,copy1Append内容==%@,copy1地址==%p,内容==%@,self.stringCopy地址==%p,内容==%@",copy1Append,copy1Append, copyStr,copyStr,self.stringCopy,self.stringCopy);


     //情况2:给属性赋NSMutableString类型的值
    NSMutableString *mStrongStr = [NSMutableString stringWithFormat:@"I am MutableStrong"];
    NSMutableString *mCopyStr = [NSMutableString stringWithFormat:@"I am MutableCopy"];
    self.stringStrong = mStrongStr;
    self.stringCopy = mCopyStr;
    ZWWLog(@"mStrongStr地址==%p, self.stringStrong地址==%p", mStrongStr,self.stringStrong);
    ZWWLog(@"mCopyStr地址==%p,self.stringCopy地址==%p", mCopyStr,self.stringCopy);


    //两个MutableString进行操作(不返回值)
    [mStrongStr appendString:@"+11111"];
    [mCopyStr appendString:@"+22222"];
    ZWWLog(@"mStrongStr地址==%p,内容==%@, self.stringStrong地址==%p,内容==%@", mStrongStr,mStrongStr,self.stringStrong,self.stringStrong);
    ZWWLog(@"mCopyStr地址==%p,内容==%@,self.stringCopy地址==%p,内容==%@", mCopyStr,mCopyStr,self.stringCopy,self.stringCopy);


}

情况1打印结果:

strongStr地址==0x1099ed230,内容=I am Strong; self.stringStrong地址==0x1099ed230,内容=I am Strong
copyStr地址==0x1099ed250,内容=I am Copy; self.stringCopy地址==0x1099ed250,内容=I am Copy

分析:

  • strongStr和self.stringStrong指针变量地址相同,说明两个变量指向的是同一个内存地址,同一个对象,所以被赋值NSString类型时,strong修饰的变量是浅拷贝
  • copyStr和self.stringCopy指针变量地址相同,说明两个变量指向的是同一个内存地址,同一个对象,所以被赋值NSString类型时,copy修饰的变量也是浅拷贝

情况1中的被赋值NSString进行值改变,打印结果:

原字符串拼接后strong1Append地址==0x604000055ae0,strong1Append内容==I am Strong+11111,strongStr地址==0x1090cf230,内容==I am Strong, self.stringStrong地址==0x1090cf230,内容==I am Strong
原字符串拼接后copy1Append地址=0x604000055060,copy1Append内容==I am Copy+22222,copy1地址==0x1090cf250,内容==I am Copy,self.stringCopy地址==0x1090cf250,内容==I am Copy

分析:

  • NSString类型的变量stringByAppendingString方法返回是一个NSString类型的变量,这个变量地址不等于原来NSString的地址(内存地址),说明不可变字符串值不可改变,如果改变(比如拼接)就会变成一个全新的变量,所以NSString类型变量改变不会影响原来变量的值
  • 无论是strong修饰还是copy修饰,都不会因为被赋值NSString类型的值的改变而改变,因为NSString类型值改变压根不会影响原来值

情况2打印结果:

mStrongStr地址==0x604000047b00, self.stringStrong地址==0x604000047b00
mCopyStr地址==0x6040000481c0,self.stringCopy地址==0x60400004b0d0

分析:

  • mStrongStr和self.stringStrong地址相同,说明strong修饰的字符串和mStrongStr指向的是同一块内存,同一个对象,说明赋值NSMutableString时,strong修饰的字符串是浅拷贝
  • mCopyStr和self.stringCopy地址不同,说明copy修饰的字符串和mCopyStr指向的不是同一块内存,不是同一个对象,说明赋值NSMutableString时,copy修饰的字符串是深拷贝

情况2中的被赋值NSMutableString进行值改变,打印结果:

mStrongStr地址==0x604000047b00,内容==I am MutableStrong+11111, self.stringStrong地址==0x604000047b00,内容==I am MutableStrong+11111
mCopyStr地址==0x6040000481c0,内容==I am MutableCopy+22222,self.stringCopy地址==0x60400004b0d0,内容==I am MutableCopy

分析:

  • NSMutableString类型的变量appendString方法返回值是void,所以拼接完之后改变的还是原来字符串,因为strong修饰的字符串是浅拷贝,所以会跟随原来值改变而改变
  • 但是copy修饰的NSString字符串被赋值是NSMutableString时,是对原对象深拷贝,所以不会因为原值的改变而改变

一个经常和这个问题一块问到的有关深浅拷贝的问题:
问题:对NSMutableString类型属性用copy修饰会有什么问题,请参考其他博客

总结:
这样看来,在不可变对象之间进行转换,strong与copy作用是一样的,但是如果在不可变与可变之间进行操作,那么就比较推荐copy, 这样可以不随着被赋值的改变而改变,这也就是为什么很多地方用copy,而不是strong修饰NSString,NSArray等存在可变不可变之分的类对象了,避免出现意外的数据操作.

猜你喜欢

转载自blog.csdn.net/wei371522/article/details/81331658