iOS-copy和strong属性@property标识符

我们都知道使用@property属性标识符修饰不可变变量如:NSString,NSArray,NSDictionary,NSSet等时都会使用copy修饰,如下:

@property (nonatomic, copy) NSString *cpStr;

那么为什么不使用strong修饰呢,如果使用strong修饰会有什么问题呢?接下来我们一起探讨一下

我声明了四组数据来进行测试

1、strong 修饰 不可变对象

@property (nonatomic, strong) NSString *strongStr;
@property (nonatomic, strong) NSArray *strongArr;
@property (nonatomic, strong) NSDictionary *strongDic;
@property (nonatomic, strong) NSSet *strongSet;


/*----strong--不可变--*/
    NSLog(@"--strong--不可变--");
    NSString *str = @"123";
    self.strongStr = str;
    str = @"666";
    NSLog(@"--strong--不可变字符串--");
    NSLog(@"str:%p    self.strongStr:%p",str,self.strongStr);
    NSLog(@"str:%@    self.strongStr:%@",str,self.strongStr);
    
    NSArray *arr = [NSArray arrayWithObjects:@1, nil];
    self.strongArr = arr;
    arr = [arr arrayByAddingObject:@8];//[NSArray arrayWithObjects:@8, nil];
    NSLog(@"--strong--不可变数组--");
    NSLog(@"arr:%p \n self.strongArr:%p",arr,self.strongArr);
    NSLog(@"arr:%@ \n self.strongArr:%@",arr,self.strongArr);
    
    NSDictionary *dic = [NSDictionary dictionaryWithObjects:@[@"123"] forKeys:@[@"key1"]];
    self.strongDic = dic;
    dic = [NSDictionary dictionaryWithObjects:@[@"666"] forKeys:@[@"key3"]];
    NSLog(@"--strong--不可变字典--");
    NSLog(@"dic:%p \n self.strongDic:%p",dic,self.strongDic);
    NSLog(@"dic:%@ \n self.strongDic:%@",dic,self.strongDic);
    
    NSSet *set = [[NSSet alloc] initWithObjects:@"one",nil];
    self.strongSet = set;
    set = [[NSSet alloc] initWithObjects:@"three", nil];
    NSLog(@"--strong--不可变集合--");
    NSLog(@"set:%p \n self.strongSet:%p",set,self.strongSet);
    NSLog(@"set:%@ \n self.strongSet:%@",set,self.strongSet);

输出结果:

内存地址不同,值不同 

2、strong 修饰 可变对象

@property (nonatomic, strong) NSString *strongMStr;
@property (nonatomic, strong) NSArray *strongMArr;
@property (nonatomic, strong) NSDictionary *strongMDic;
@property (nonatomic, strong) NSSet *strongMSet;


/*----strong--可变--*/
    NSLog(@"--strong--可变--");
    NSMutableString * mString = [NSMutableString stringWithString:@"123"];
    self.strongMStr = mString;
    [mString appendString:@"666"];
    NSLog(@"--strong--可变字符串--");
    NSLog(@"mString:%p    self.strongMStr:%p",mString,self.strongMStr);
    NSLog(@"mString:%@    self.strongMStr:%@",mString,self.strongMStr);
    
    NSMutableArray *mArr = [NSMutableArray arrayWithObjects:@1, nil];
    self.strongMArr = mArr;
    [mArr addObject:@8];
    NSLog(@"--strong--可变数组--");
    NSLog(@"mArr:%p \n self.strongMArr:%p",mArr,self.strongMArr);
    NSLog(@"mArr:%@ \n self.strongMArr:%@",mArr,self.strongMArr);
    
    NSMutableDictionary *mDic = [NSMutableDictionary dictionaryWithObjects:@[@"123"] forKeys:@[@"key1"]];
    self.strongMDic = mDic;
    [mDic setValue:@"666" forKey:@"key3"];
    NSLog(@"--strong--可变字典--");
    NSLog(@"mDic:%p \n self.strongMDic:%p",mDic,self.strongMDic);
    NSLog(@"mDic:%@ \n self.strongMDic:%@",mDic,self.strongMDic);
    
    NSMutableSet *mSet = [[NSMutableSet alloc] initWithObjects:@"one", nil];
    self.strongMSet = mSet;
    [mSet addObject:@"three"];
    NSLog(@"--strong--可变集合--");
    NSLog(@"mSet:%p \n self.strongMSet:%p",mSet,self.strongMSet);
    NSLog(@"mSet:%@ \n self.strongMSet:%@",mSet,self.strongMSet);

输出结果:

内存地址相同,值相同  

3、copy 修饰 不可变对象

@property (nonatomic, copy) NSString *cpStr;
@property (nonatomic, copy) NSArray *cpArr;
@property (nonatomic, copy) NSDictionary *cpDic;
@property (nonatomic, copy) NSSet *cpSet;


/*----copy--不可变--*/
    NSLog(@"");
    NSLog(@"--copy--不可变--");
    NSString *cpStr = @"123";
    self.cpStr = cpStr;
    cpStr = @"666";
    NSLog(@"--copy--不可变字符串--");
    NSLog(@"cpStr:%p    self.cpStr:%p",cpStr,self.cpStr);
    NSLog(@"cpStr:%@    self.cpStr:%@",cpStr,self.cpStr);
    
    NSArray *cpArr = [NSArray arrayWithObjects:@1,nil];
    self.cpArr = cpArr;
    cpArr = [NSArray arrayWithObjects:@8, nil];
    NSLog(@"--copy--不可变字数组--");
    NSLog(@"cpArr:%p \n self.cpArr:%p",cpArr,self.cpArr);
    NSLog(@"cpArr:%@ \n self.cpArr:%@",cpArr,self.cpArr);
    
    NSDictionary *cpDic = [NSDictionary dictionaryWithObjects:@[@"123"] forKeys:@[@"key1"]];
    self.cpDic = cpDic;
    cpDic = [NSDictionary dictionaryWithObjects:@[@"666"] forKeys:@[@"key3"]];
    NSLog(@"--copy--不可变字典--");
    NSLog(@"cpDic:%p \n self.cpDic:%p",cpDic,self.cpDic);
    NSLog(@"cpDic:%@ \n self.cpDic:%@",cpDic,self.cpDic);
    
    NSSet *cpSet = [[NSSet alloc] initWithObjects:@"one", nil];
    self.cpSet = cpSet;
    cpSet = [[NSSet alloc] initWithObjects:@"three", nil];
    NSLog(@"--copy--不可变集合--");
    NSLog(@"cpSet:%p \n self.cpSet:%p",set,self.cpSet);
    NSLog(@"cpSet:%@ \n self.cpSet:%@",set,self.cpSet);

输出结果

内存地址不同,值不同  

4、copy 修饰 可变对象

@property (nonatomic, copy) NSString *cpMStr;
@property (nonatomic, copy) NSArray *cpMArr;
@property (nonatomic, copy) NSDictionary *cpMDic;
@property (nonatomic, copy) NSSet *cpMSet;


/*----copy--可变--*/
    NSLog(@"--copy--可变--");
    NSMutableString * cpMStr = [NSMutableString stringWithString:@"123"];
    self.cpMStr = cpMStr;
    [cpMStr appendString:@"666"];
    NSLog(@"--copy--可变字符串--");
    NSLog(@"cpMStr:%p    self.cpMStr:%p",cpMStr,self.cpMStr);
    NSLog(@"cpMStr:%@    self.cpMStr:%@",cpMStr,self.cpMStr);
    
    NSMutableArray *cpMArr = [NSMutableArray arrayWithObjects:@1, nil];
    self.cpMArr = cpMArr;
    [cpMArr addObject:@6];
    NSLog(@"--copy--可变数组--");
    NSLog(@"cpMArr:%p \n self.cpMArr:%p",cpMArr,self.cpMArr);
    NSLog(@"cpMArr:%@ \n self.cpMArr:%@",cpMArr,self.cpMArr);
    
    NSMutableDictionary *cpMDic = [NSMutableDictionary dictionaryWithObjects:@[@"123"] forKeys:@[@"key1"]];
    self.cpMDic = cpMDic;
    [cpMDic setValue:@"666" forKey:@"key3"];
    NSLog(@"--copy--可变字典--");
    NSLog(@"cpMDic:%p \n self.cpMDic:%p",cpMDic,self.cpMDic);
    NSLog(@"cpMDic:%@ \n self.cpMDic:%@",cpMDic,self.cpMDic);
    
    NSMutableSet *cpMSet = [[NSMutableSet alloc] initWithObjects:@"one", nil];
    self.cpMSet = cpMSet;
    [cpMSet addObject:@"three"];
    NSLog(@"--copy--可变集合--");
    NSLog(@"cpMSet:%p \n self.cpMSet:%p",mSet,self.cpMSet);
    NSLog(@"cpMSet:%@ \n self.cpMSet:%@",mSet,self.cpMSet);

 输出结果

内存地址不同,值不同 

总结:

在这里我们会发现,只有在第二种情况:strong修饰 可变对象时,如果可变对象的值发生了改变,那么strong修饰的对象会跟着改变。

当使用 strong 修饰属性的时候,属性的setter方法会直接强引用该对象,这样当原对象的值发生改变时,新对象的属性也跟随改变

对于NSString,NSArray,NSDictionary,NSSet等这些不可变对象,如果对这个对象进行可变对象的操作则会产生异常crash。

因此,我们使用copy修饰NSString,NSArray,NSDictionary,NSSet等这些不可变对象,copy可以让本对象不受外界(子对象)影响,无论给我传入的是一个可变对象还是一个不可变对象,都能保证自身持有的是一个不可变副本;防止可变对象更改自身的值的时候不会影响到property对象属性。

针对不可变对象使用copy修饰,针对可变对象使用strong修饰。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值