字符串可以用strong修飾?
開發(fā)中,我們經常遇見屬性變量修飾問題(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
由以上就可以看出來了,開發(fā)中如果遇見屬性字符串用strong修飾,在將可變字符串賦值的情況,就可能改變了可變字符串,同時也改變了用strong修飾的字符串值,根本原因就是這2個字符串指針(地址不同)但是卻指向了同一片內存區(qū)域。
為了避免這種情況發(fā)生,開發(fā)中盡量對不可變的字符、數組、字典用copy修飾,可變的則用strong修飾。