iOS中copy和strong修飾符的區別

iOS中copy和strong修飾符的區別數組

//用copys修飾的生成的都是不可變的對象 ,若是調用可變類型方法的直接報錯
@property(nonatomic,copy)NSString * cpStr;
@property(nonatomic,strong)NSString *strongStr;

 

1.當copy的對象類型爲不可變對象如NSString類型時,和Strong修飾做用是同樣的app

  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);

//打印信息:atom

str==0x105086190,spa

 cpstring==0x105086170,code

 storngstr==0x105086170orm

----------對象

str==haha,blog

 cpstring==wxwx,內存

 storngstr==wxwxstring

很明顯二者指向的是同一塊內存地址,因爲指向不可變的對象不用擔憂對象值改變引發原始值的變化

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等)

相關文章
相關標籤/搜索