iOS中copy和strong修飾符的區別
//用copys修飾的生成的都是不可變的對象 ,如果調用可變類型方法的直接報錯 @property(nonatomic,copy)NSString * cpStr; @property(nonatomic,strong)NSString *strongStr;
1.當copy的對象類型為不可變對象如NSString類型時,和Strong修飾作用是一樣的
NSString *str = @"wxwx"; self.cpStr = str; self.strongStr = str ; str = @"haha"; NSLog(@"str==%p,\n cpstring==%p,\n storngstr==%p",str,_cpStr,_strongStr); NSLog(@"str==%@,\n cpstring==%@,\n storngstr==%@",str,_cpStr,_strongStr);
//打印信息:
str==0x105086190,
cpstring==0x105086170,
storngstr==0x105086170
----------
str==haha,
cpstring==wxwx,
storngstr==wxwx
很明顯兩者指向的是同一塊內存地址,由於指向不可變的對象不用擔心對象值改變引起原始值的變化
2.再來看兩者指向可變對象的時候
NSMutableString *str = [NSMutableString stringWithFormat:@"caca"]; self.cpStr = str; self.strongStr = str ; [str insertString:@"ha21" atIndex:0]; NSLog(@"str==%p,\n cpstring==%p,\n storngstr==%p",str,_cpStr,_strongStr); NSLog(@"str==%@,\n cpstring==%@,\n storngstr==%@",str,_cpStr,_strongStr);
可以看到打印信息為:
str==0x600002569aa0,
cpstring==0xf3479ef8a5126e6a,//指向的地址已經改變
storngstr==0x600002569aa0
----------------------
str==ha21caca,
cpstring==caca,//copy對象的值還是原始值。
storngstr==ha21caca
由於指向可變的對象,用copy修飾的話就算對象的值發生改變也不會影響本身
3.深拷貝,淺拷貝
淺拷貝:指向可變對象的時候利用copy,新產生一份內存,但子對象還是指向原先內存。
深拷貝:子對象也重新生成一份內存。
如下代碼展示了淺拷貝:
NSMutableArray *arr1 =[ NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"tom"],[NSMutableString stringWithString:@"jack"], nil]; NSArray*arr2 = [arr1 copy]; [arr1[0] appendString:@" new value"]; NSLog(@"淺拷貝---arr1==%@,arr2===%@ \n 地址---arr1=%p,arr2=%p",arr1,arr2,arr1,arr2);
查看log:
淺拷貝---arr1==( "tom new value", jack ),arr2===( "tom new value", jack ) 地址---arr1=0x1020309e0,arr2=0x102030de0
很明顯,arr1,arr2的內存是不一致的,但里面的子對象指向的內存還是同一塊.
深拷貝:實現深拷貝的方法,需要將子對象也都復制一份。比如通過遍歷數組中的每個對象並未沒個對象創建新的拷貝.
下面通過歸檔實現深拷貝:
NSMutableArray *agearr = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"jack"],[NSMutableString stringWithString:@"tom"], nil]; NSData *data = [NSKeyedArchiver archivedDataWithRootObject:agearr]; NSMutableArray* agearr2 = [NSKeyedUnarchiver unarchiveObjectWithData:data]; NSMutableString *obj1 = agearr2[0]; [obj1 appendString:@"----some value"]; NSMutableArray *tarr = [agearr mutableCopy]; [[tarr objectAtIndex:0] appendString:@"==lepp"]; NSLog(@"age1===%@\n age2===%@ tarr==%@",agearr,agearr2,tarr);
查看Log:
age1===( "jack==lepp", tom ) age2===( "jack----some value", tom ) tarr==( "jack==lepp", tom )
總結:
當屬性為不可變時用copy(防止屬性值被篡改),指向可變屬性時用strong(注:如果還是用copy,由於copy返回的都是不可變的對象,一旦調用不可變對象的方法就會引起崩潰,所以這里也不能用copy)
對於其他可變非可變類同理(NSArray,NSMutableArray等)