天天看点

NSString为啥要使用Copy属性

一直知道NSSting作为属性使用时,最好使用Copy,这样原指针指向的内容发生变化,不会影响到NSString属性。

那么,如果我没有使用Copy,而是使用retain、strong的时候,会导致原指针内容发生变化的时候,NSString属性的指也发生变化呢?

对此,我做了一点实验:

属性如下定义

@property (nonatomic, strong) NSString *string1;
@property (nonatomic, copy) NSString *string2;
           

测试结果如下

1、字符串常量

- (void)test1 {
    NSString *testString = @"test1";
    self.string1 = testString;
    self.string2 = testString;
    testString = @"test2";
    NSLog(@"%@, %@", self.string1, self.string2);
}
           

输出结果:test1, test1

2、使用[NSString stringWIthFormate:]生成的NSString

- (void)test2 {
    NSString *testString = [NSString stringWithFormat:@"%@", @"test1"];
    self.string1 = testString;
    self.string2 = testString;
    testString = [NSString stringWithFormat:@"%@", @"test2"];
    NSLog(@"%@, %@", self.string1, self.string2);
}
           

输出结果:test1, test1

从这两个结果看来,NSString属性设置为strong和copy好像没什么区别,看起来好像都是对指针进行了拷贝。

别急,我们再看下面的两个测试结果:

3、使用NSMutableString

- (void)test3 {
    NSMutableString *testString = [NSMutableString stringWithFormat:@"%@", @"test1"];
    self.string1 = testString;
    self.string2 = testString;
    [testString replaceOccurrencesOfString:@"1" withString:@"2" options:0 range:NSMakeRange(0, testString.length)];
    NSLog(@"%@, %@", self.string1, self.string2);
}
           

输出结果:test2, test1

发生变化了!!

又有同学说了,这个和上面的情况不一样啊,testString使用的是不同的方法,结果很有可能不一样啊,没关系,再来看一个

4、还是使用NSMutableString

- (void)test4 {
    NSMutableString *testString = [NSMutableString stringWithFormat:@"%@", @"test1"];
    self.string1 = testString;
    self.string2 = testString;
    testString = [NSMutableString stringWithFormat:@"%@", @"test1"];
    NSLog(@"%@, %@", self.string1, self.string2);
}
           

输出结果:test1, test1

没有发生变化!!

这是什么原因呢,我们来分析一下:

对于1、2、4三种情况,testString都是进行了重新赋值,testString指针指向了另一个内存地址,testString原来指向的内容并没有发生变化,所以,无论是strong还是copy,string1和string2指向的内容都不会发生变化;

而对于3来说,是对testString指向的内容进行了修改,而string1和testString指向的是同一个内存地址,所以string1指向的内容发生了变化;而string2对指针进行了拷贝,它和testString指向的是两个内存地址,所以testString指向的内容发生变化时,string2不受影响;

结论:

对于NSMutableString来说,它本身是可变的,所以最好使用copy,这样可以避免原指针内容发生变化,导致属性的值也发生变化,可以有效的避免一些莫名的BUG。

对于NSString类型来说,它本身不允许被修改,所以使用strong和copy都不会有影响。但是,由于NSString兼容NSMutableString,如果属性指针指向了NSMutableString类型的字符串,就会出现3的情况,所以最好也是使用copy。

总之,在定义NSString属性的时候,使用copy才是万无一失的。

继续阅读