什么情况下需要用到copy关键字?
1、@property声明NSString、NSArray、NSDictionary;
2、对对象进行复制;
3、block也经常使用copy关键字
@property声明NSString、NSArray、NSDictionary为什么要用copy关键字?
copy此特质所表达的所属关系与strong类似。然而设置方法并不保留新值,而是将其“拷贝” (copy)。 当属性类型为NSString时,经常用此特质来保护其封装性,因为传递给设置方法的新值有可能指向一个NSMutableString类的实例。这个类是NSString的子类,表示一种可修改其值的字符串,此时若是不拷贝字符串,那么设置完属性之后,字符串的值就可能会在对象不知情的情况下遭人更改。所以,这时就要拷贝一份“不可变” (immutable)的字符串,确保对象中的字符串值不会无意间变动。只要实现属性所用的对象是“可变的” (mutable),就应该在设置新属性值时拷贝一份。
示例1:
//声明属性
@property(nonatomic, copy) NSMutableArray *array;
//执行代码
NSMutableArray *temp = [NSMutableArray arrayWithObjects:@1, @2, @3, nil];
self.array = temp;
[temp removeObjectAtIndex:0];
NSLog(@"%@", temp);
NSLog(@"%@", self.array);
//执行结果
2017-04-17 13:38:57.210 newTest[4255:1947617] (
2,
3
)
2017-04-17 13:38:57.211 newTest[4255:1947617] (
1,
2,
3
)
示例2:
//声明属性
@property(nonatomic, strong) NSMutableArray *array;
//执行代码
NSMutableArray *temp = [NSMutableArray arrayWithObjects:@1, @2, @3, nil];
self.array = temp;
[temp removeObjectAtIndex:0];
NSLog(@"%@", temp);
NSLog(@"%@", self.array);
//结果
2017-04-17 13:44:46.921 newTest[4258:1948649] (
2,
3
)
2017-04-17 13:44:46.922 newTest[4258:1948649] (
2,
3
)
通过上面两个示例可以发现:
属性指向可变对象时,
1、使用strong关键字修饰的属性,在可变对象发生变化时,属性也会发生变化;
2、copy关键字修饰的属性,得到的是可变对象的不可变副本,在可变对象发生变化时,属性不会发生变化;
注: 因为copy关键字修饰的属性,得到的是对象的不可变副本,所有对属性进行增、删、改操作会引起崩溃;
示例3:
//声明属性
@property(nonatomic, strong) NSMutableArray *array;
//执行代码
1 NSMutableArray *temp = [NSMutableArray
2 arrayWithObjects:@1, @2, @3, nil];
3 self.array = temp;
4 [self.array addObject:@4];
//结果
在执行第4条语句时,崩溃;
block使用copy关键字
block使用copy是从MRC遗留下来的“传统”,在MRC中,方法内部的block是在栈区的,使用copy可以把它放到堆区.在ARC中写不写都行:对于block使用copy还是strong效果是一样的,但写上copy也无伤大雅,还能时刻提醒我们:编译器自动对block进行了copy操作。