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

Posted MinggeQingchun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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修饰。

以上是关于iOS-copy和strong属性@property标识符的主要内容,如果未能解决你的问题,请参考以下文章

iOS 属性之 strong和copy修饰的区别

OC基础 - strong和copy的区别【转载】

iOS strong与weak的使用

Objc中为何某些类的属性要设置为copy而不是strong?

NSString属性什么时候用copy,什么时候用strong?

NSString 属性为啥用copy 不用strong