自我总结 :
strong :
强应用,指针, 赋值后改变也都会改变
copy :
分配一个新的地址, 如果赋值后改变赋值的内容, 被赋值不会改变 如下述
weak :
弱应用,引用计数不会+1 释放后会被置空
assign 简单变量使用
block 做属性的时候也用copy
typedef void (^Block)(NSString *name);
@property (nonatomic, copy) Block testBlock;
修饰符:
· 声明变量的修饰符:__strong, __weak, __unsafe_unretained, __autoreleasing;
· 声明属性的修饰符:strong, weak, unsafe_unretained。
· 对象和Core Foundation-style对象直接的转换修饰符号:__bridge,__bridge_retained或CFBridgingRetain, __bridge_transfer或CFBridgingRelease。
· 对于线程的安全,有nonatomic,这样效率就更高了,但是不是线程的。如果要线程安全,可以使用atomic,这样在访问是就会有线程锁。
别人的总结
· 所有的属性,都尽可能使用nonatomic,以提高效率,除非真的有必要考虑线程安全。
· NSString:通常都使用copy,以得到新的内存分配,而不只是原来的引用。
· strong:对于继承于NSObject类型的对象,若要声明为强使用,使用strong,若要使用弱引用,使用__weak来引用,用于解决循环强引用的问题。
· weak:对于xib上的控件引用,可以使用weak,也可以使用strong。
· __weak:对于变量的声明,如果要使用弱引用,可以使用__weak,如:__weak typeof(Model) weakModel = model;就可以直接使用weakModel了。
· __strong:对于变量的声明,如果要使用强引用,可以使用__strong,默认就是__strong,因此不写与写__strong声明都是一样的。
· unsafe_unretained:这个是比较少用的,几乎没有使用到。在所引用的对象被释放后,该指针就成了野指针,不好控制。
· __unsafe_unretained:也是很少使用。同上。
· __autoreleasing:如果要在循环过程中就释放,可以手动使用__autoreleasing来声明将之放到自动释放池。
Objective-C属性修饰符strong和copy的区别
From: https://segmentfault.com/a/1190000002520583
问题描述
在定义一个类的property时候,为property选择strong还是copy特别注意和研究明白的,如果property是NSString或者NSArray及其子类的时候,最好选择使用copy属性修饰。为什么呢?这是为了防止赋值给它的是可变的数据,如果可变的数据发生了变化,那么该property也会发生变化。
代码示例
还是结合代码来说明这个情况
@interface Person : NSObject
@property (strong, nonatomic) NSArray *bookArray1;
@property (copy, nonatomic) NSArray *bookArray2;
@end
@implementation Person
//省略setter方法
@end
//Person调用
main(){
NSMutableArray *books = [@[@"book1"] mutableCopy];
Person *person = [[Person alloc] init];
person.bookArray1 = books;
person.bookArray2 = books;
[books addObject:@"book2"];
NSLog(@"bookArray1:%@",person.bookArray1);
NSLog(@"bookArray2:%@",person.bookArray2);
}
我们看到,使用strong修饰的person.bookArray1输出是[book1,book2],而使用copy修饰的person.bookArray2输出是[book1]。这下可以看出来区别了吧。
备注:使用strong,则person.bookArray1与可变数组books指向同一块内存区域,books内容改变,导致person.bookArray1的内容改变,因为两者是同一个东西;而使用copy,person.bookArray2在赋值之前,将books内容复制,创建一个新的内存区域,所以两者不是一回事,books的改变不会导致person.bookArray2的改变。
说到底,其实就是不同的修饰符,对应不同的setter方法,
- strong对应的setter方法,是将_property先release(_property release),然后将参数retain(property retain),最后是_property = property。
- copy对应的setter方法,是将_property先release(_property release),然后拷贝参数内容(property copy),创建一块新的内存地址,最后_property = property。
文章评论