整理一下关于OC中property的知识。
概念
@property相信大家也都很熟悉了。在iOS开发中,@property
一般用来声明对象或者属性,使用@property
声明的对象就能通过点语法来进行调用。在几年以前,使用@property
的话,会和@synthesize
配套使用,令编译器能够合成访问器方法。不过后来都默认自动合成访问器方法。
@property Object *object
和Object *object1
有什么区别? object1是一个实例变量,存在于Object实例内存中。object则是该对象的属性,能够通过点语法来进行访问。大多数属性都是基于实例变量(ivar)进行访问。简单点说就是object包含了getter和setter方法以及_object这个实例变量,而object1就仅仅是个实例变量,并不含有访问器方法
属性
property的属性可以分为四类:
* 线程安全:atomic/nonatomic
* 访问权限:readonly/readwrite
* 内存管理(ARC):assign/weak/strong/copy
* 内存管理(MRC):assign/retain/copy/unsafe_unretained
* 指定访问器方法:getter=/setter=
线程安全
-
atomic:
atomic
(原子性)是property的默认值之一。原子性保证了该属性的线程安全。如果在线程B调用setter的时候,有个线程A要调用getter的话,那么线程A会获取到一个可变的值。atomic
并不常用,因为会影响性能,较低效率。如果使用atomic
的话且想要实现自定义的访问器方法,必须实现getter和setter方法,缺一不可。 -
nonatomic:
nonatomic
(非原子性)跟atomic
相反。如果线程A在获取一个非原子属性的字符串的时,线程B要将字符修改成”Apple“,而线程C要修改成”Pen“的话,A获取出来的值是不确定的,有可能会使程序crash。非原子性并不是线程安全,但是胜在够快。
访问权限
-
readwrite: property默认值之一。告诉编译器生成getter和setter
-
readonly: 告诉编译器只生成getter即可。通常的用法是,如果想将此属性暴露给其他类的话,在.h文件中,将其声明为
readonly
,在.m文件,将其声明为readwrite
.这样的话,外部的其他文件就只能获取,不能修改。
内存管理
-
strong: property默认值之一。将属性声明为
strong
的话,每当使用该属性时,会增加引用计数(ARC会替我们完成这项工作,在MRC时代就需要自己计数)。也就是说实例变量会一直在内存中持有此属性,直到引用计数为0.使用strong
的话有可能会引起引用循环,但是我们可以使用weak来解决此问题 -
weak: 给定一个指向对象且不会增加引用计数的指针。在其他类或者对象强引用此属性时,其会保持有一个有效的指针。如果没有其他对象要引用它的话,马上就会变为nil。这就避免了引用循环。
-
assign: 常用于修饰
int
,long
等原始类型。与weak类似 -
copy: 与
strong
类似,不过它会复制对象的值,且强引用这个蓝本。被copy的对象必须遵循NSCopying的协议 -
retain:
strong
的旧版本。 -
unsafe_unretained: 与
weak
类似,但是在没有其他对象进行引用时,并不会将值设置为nil
修改访问器方法名称
- getter=: 自定义访问器的getter名称。
- setter=: 自定义访问器的setter名称。
Swift
Xcode 6.3之后,添加了nonnull
,nullable
和null_resetable
来对应Swift中的Optional类型。