欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-01-15 08:24:10
...

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等存在可变不可变之分的类对象了,避免出现意外的数据操作.

相关标签: strong copy