最近在开发过程中看到了针对NSString属性的各种写法,包括我自己,痛定思痛,决定写一遍文章出来摆正三观。
先说说我在项目中看到的对NSString属性的写法:
1. @property(nonatomic,strong)NSString *tmpStr;
- (void)xxxFunc:(NSString *)str
{
//_tmpStr = str; // 写法1
//self.tmpStr = str; // 写法2
//
}
2. @property(nonatomic,copy) NSString *tmpStr;
- (void)xxxFunc:(NSString *)str
{
//_tmpStr = str; // 写法1
//self.tmpStr = str; // 写法2
//
}
NSString为不可变类型,而NSMutableString为可变类型,那么使用strong和copy到底有什么区别呢?
1. 使用strong,表明该变量拥有所有权,而这个属性就有可能指向一个可变对象,如果这个可变对象在外部修改了,那么会影响该属性
2. 使用copy, 表明该变量不受外部影响,本身持有一个不可变副本,即使传入的是一个可变对象
具体代码如下:
1. @property (nonatomic,strong)NSString *string;
NSLog(@"modify string before");
NSMutableString *mutableStr = [@"mutablestring"mutableCopy];
[selftestString:mutableStr];
NSLog(@"modify string after");
[mutableStr appendString:@" modify"];
NSLog(@"%@",self.string);
-(void)testString:(NSString *)str
{
self.string = str;
NSLog(@"%@",self.string);
}
结果是什么呢?? 很清楚的看到,即使你声明了NSString的不可变类型,但是还是被外部给影响了。那么如果self.string = str;改成_string = str;结果还是一样
2016-09-07 10:57:59.804 testFunctionString[1373:73860] modify string before
2016-09-07 10:57:59.804 testFunctionString[1373:73860] mutablestring
2016-09-07 10:57:59.804 testFunctionString[1373:73860] modify string after
2016-09-07 10:57:59.804 testFunctionString[1373:73860] mutable string modify
2. @property (nonatomic,copy) NSString *string;
其余不变,运行代码,可以看到结果如下:可以看到NSString的对象不受外部的影响
2016-09-07 11:02:57.164 testFunctionString[1385:76130] modify string before
2016-09-07 11:02:57.164 testFunctionString[1385:76130] mutablestring
2016-09-07 11:02:57.165 testFunctionString[1385:76130] modify string after
2016-09-07 11:02:57.165 testFunctionString[1385:76130] mutable string
3. 如果在2的基础我,修改self.string = str;为_string = str;会咋样呢:
继续运行程序,得出的结果如下:可以看到结果被改变了
2016-09-07 11:04:52.928 testFunctionString[1396:77501] modify string before
2016-09-07 11:04:52.928 testFunctionString[1396:77501] mutablestring
2016-09-07 11:04:52.928 testFunctionString[1396:77501] modify string after
2016-09-07 11:04:52.928 testFunctionString[1396:77501] mutable string modify
总结:
1. 对于不可变对象,使用copy来防止改变结果,因为copy返回的是不可变对象,同时使用setter方法来赋变量,否则都危险
2. 对于可变对象,使用strong来拥有所有权
3. 对于可变对象,使用copy后,不能调用addobject等可变对象的函数,否则崩溃