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标识符的主要内容,如果未能解决你的问题,请参考以下文章
Objc中为何某些类的属性要设置为copy而不是strong?