为了代码的可读性和内存的正常管理,则需要对一些对象的声明遵循一定的原则,而不是乱用@property的属性。笔者是自学的编程学,曾在参数的选择上纠结不少次,只晓得用而不明其意,就像一个不可变数组NSArray,相信大家都用过是用strong去修饰,而我在一些项目总看到好多都是用copy修饰,而且一个大牛也建议我用copy修饰。接下来就带大家捋一捋各参数的含义与用法。
@propert与@synthesize;
nonatomic与atomic;
readonly与readwrite;
strong与weak;
copy、retain与assign;
1、setter与getter方法
1)、在头文件(.h)中
int count;
//setter -- 手动设置获取实例变量的方法
- (void)setCount:(int)newCount;
//getter -- 手动设置设置实例变量的方法
- (int)count;
2)、在实现文件(.m)中
- (void)setCount:(int)newCount{
count = newCount;
}
- (int)count{
return count;
}
2、@propert与@synthesize
1)、@property
@property是声明属性的语法,它可以快速的为实例变量创建存取器,并且允许通过点语法使用存取器。
存取器:用于获取和设置实例变量的方法。getter是用于获取实例变量的存取器,setter是用于设置实例变量的存取器。
通常使用@property声明属性时,setter与getter方法的声明与实现都可以省略。
2)、@synthesize
@synthesize同样是声明属性的语法,它不同@property的是在.m文件实现。在.h文件中声明完property属性之后,会自动生成下划线,如_age、_name;如果不想要下划线,那么就可以使用@synthesize去修饰,例如,在.m中写@synthesize age;那么_age就会变成age。
3、nonatomic与atomic
1)、atomic
atomic是原子操作,提供线程安全,声明属性系统默认是atomic的,运行时比较耗费系统资源。
2)、nonatomic
nonatomic是非原子性操作,不提供线程安全,但在运行时相比atomic效率更高。
3)、两者之间的区别
atomic和nonatomic的区别在于,系统自动生成的getter/setter方法不一样。如果你自己写getter/setter,那atomic/nonatomic/retain/assign/copy等这些关键字只起提示作用,写不写都一样。
对于atomic的属性,系统生成的getter/setter会保证get、set操作的完整性,不受其他线程影响。比如,线程 A 的getter方法运行到一半,线程 B 调用了setter,那么线程 A 的getter还是能得到一个完好无损的对象。而nonatomic就没有这个保证了。所以,nonatomic的速度要比atomic快。不过atomic可并不能保证线程安全。如果线程 A 调了 getter,与此同时线程 B 、线程 C 都调了setter——那最后线程 A get 到的值,3种都有可能:可能是 B、C set 之前原始的值,也可能是 B set 的值,也可能是 C set 的值。同时,最终这个属性的值,可能是 B set 的值,也有可能是 C set 的值。
4、readonly与readwrite
1)、readonly
设置的属性只可读不能写(即在该类中某一属性已经设置好了固定的值,当调用该类使用这一属性时不能再次设值)。
2)、readwrite
设置的属性可以读写,系统默认的属性。
5、strong与weak
1)、strong
strong声明的属性在赋值时调用被指向对象的retain方法,使其引用计数加1。在OC中一般对象的声明是使用strong,但有时项目的需要,为了避免内存泄漏和BUG的影响而使用copy、assign和weak去声明。
2)、weak
weak相对于strong来说不增加对象的引用计数,也不持有对象,对象消失后,指针自动变成nil。
3)、strong与weak的区别
从1)和2)中可以看出部分的区别,接下来我继续带大家讨论下:
首先声明两个属性view1和view2,view1用strong声明,而view2用weak声明;
再在程序中alloc一个view3和view4;
然后view1指向view3,view2指向view4;
最后使view3、view4同时置nil,打印view1和view2的值。
通过运行可以发现view1仍然分配了内存地址,而view2=null。
6、copy、retain与assign
1)、copy
setter方法进⾏行Copy操作,表示重新建立一个引用计数为1的对象,然后释放旧的值,通常用于NSString和block
2)assign
是默认属性,只可以对基本数据类型(如CGFloat,NSInteger,Bool,int,代理对象)等使⽤。 该方式会使对象直接赋值而不会进行retain操作。
3)、retain
表示对对象和及其⼦子类对象release旧值,再retain新值,使对象的应⽤计数增加⼀。 该属性只能使⽤用于obejective-c类型对象,不能用于Core Foundation对象。
4)、综述
retain是指针拷贝;
copy是内容拷贝,在拷贝之前,都会释放旧的对象。
assign:简单赋值,不更改索引计数(Reference Counting)。
7、读者V587
如果有不妥之处请大家指出,谢谢。