使用OC等面向对象语言编程时,“对象(object)”就是“基本结构单元(building block)”。开发者可以通过对象来存储传递数据。对象之间传递数据并执行任务的过程就是“消息传递(Messaging)”。当程序运行起来之后,为其提供相关支持的代码叫做“运行期环境(runtime)”。它提供了一些使得对象之间能够传递信息的重要函数,并包含创建类实例所用的所有逻辑。
属性
属性是OC的特有属性,用于封装对象中的数据。实例变量通过“存取方法(access method)”来访问。获取方法(getter)读取变量值,设置方法(setter)写入变量值。
- 使用 @property 来修饰变量,系统自动合成getter和setter方法。
- 使用 @synthesize 来指定实例变量的名字,重新更换名字
- 使用 @dynameic 定义变量,不用自动创建属性所用的实例变量,也不要创建存取方法
属性的特质
特质(attribute)
-
1.原子性
默认由编译器合成的方法会通过锁定机制确保其原子性(atomicity),如果属性具备nonatomic特质,则不使用同步锁。如果一个属性不具备nonatomic特质,那她就是原子的(atomic)。
-
2.读写权限
具备读写(readwrite)特质的属性拥有getter和setter方法。如果属性由@synthesizer来实现,编译器会自动生成这个连个方法。
具备只读(readonly)特质的属性仅仅有getter方法。只有该属性被@ synthesizer来实现时候,才具备setter方法。
-
3.内存管理语义
属性用户封装数据,而数据有自己的所有权语义。
assgin 执行对纯量类型简单赋值操作,例如:CGFloat、NSInteger
strong 给属性定义了一种拥有关系(owning relationship)。为该属性设置新值时,会先保留新值,并释放旧值,在把新值赋值上去。
weak 给属性定义一种非拥有关系(nonowning relationship)。为该属性设置新值时,既不保留新值,也不释放旧值。当属性被销毁时,属性值会清空。
copy 不保存新值,将其拷贝。如果被别人修改,可以有备份文件。
unsafe_unretained 非拥有关系,当对象被销毁时候,属性值不会被自动清空。
-
4.方法名
getter=<name> 指定getter方法名。比如给BOOL加getter=isON。
setter=<name> 指定setter方法名,一般不常用。
尽量使用不可变对象。
atomic和nonatomic区别
具备atomic特质的获取方法会通过锁定机制来确保其操作的原子性。例如:两个线程读写同一个属性,无论何时都能看到有效的属性值。如果不加锁,当一个线程改变了属性值,另外一个也恰好在更改,就会造成属性读取不一致,导致后续的问题。
看到的属性几乎都是非原子性的原因:
- 在iOS开发中使用同步锁开销大,引发性能问题
- 不能保证线程安全(thread safty)
总结
- 使用@property来定义对象
- 通过特质来正确指定对象语义
- 使用变量,遵从该属性声明的定义
- iOS开发尽可能使用nonatomic