Objective-C Property

212 阅读3分钟

整理一下关于OC中property的知识。

概念

@property相信大家也都很熟悉了。在iOS开发中,@property一般用来声明对象或者属性,使用@property声明的对象就能通过点语法来进行调用。在几年以前,使用@property的话,会和@synthesize配套使用,令编译器能够合成访问器方法。不过后来都默认自动合成访问器方法。

@property Object *objectObject *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之后,添加了nonnullnullablenull_resetable来对应Swift中的Optional类型。