第二章:对象、消息、运行时
6. 理解属性的含义:是一种o-c的特性,用于封装数据
- 理解@synthesize 自动合成存取方法和下划线的实例变量
- 理解 @dynamic 不要自动合成存取方法和实例变量,需要手动创建,编译器不会检查,即使没有实现,但是运行期如果还没有,那么调用的时候就会崩溃了
- 理解属性特质:不同的特质会影响编译器生成的存取方法
a. 原子性:atomic 和 nonatomic, 默认是原子的,会通过锁机制确保原子性,但是通常不采用原子性,因为在ios 开发中存在严重的性能问题,另外并不能
保证 “线程安全”
b. 读写权限:readwrite 和readonly ; 前者就有存取(getter &setter)方法, 后者只有取(getter)方法,可以在类扩展中重写具有readonly 的属性.
c. 内存管理语义:只会影响设置方法;assgin 、weak 、unsafe_unretained、strong、copy
d. 方法名:可以重新命名存取方法名:语法-> getter = <name> ;setter = <name>
例如:@property(nonatomic , getter = isOpen) BOOL open;
7. 在对象内部尽量直接访问实例变量
- 建议访问的时候采用直接访问的形式,设置实例变量的时候采用属性来做,这样既能保证效率,又能监控写入操作。
分析:直接访问实例变量的优缺点:
a. 由于不经过oc 的方法派发,所以直接访问实例变量的速度比较快
b. 内存管理语义就显示的多余了
c. 不会触发键值观察kvo通知
d. 通过属性来访问可以方便调试,监听访问时机
*另外要注意针对init 的问题,初始化的使用建议采用直接访问实例变量的方法,因为子类可能重写父类属性的设置方法,如果该场景下父类里面调用了子类方法,那么可能父类会直接调用子类方法,是的父类不能正常初始化了,这不是我们要的结果
*针对惰性初始化的实例,必须调用属性方法访问了,没啥可说的
8. 理解对象等同性:根据需要重新定义自己的等同性判定方法;NSObject 提供了下面的两个基本的方法:
- (BOOL) isEqual:(id)object;
- (NSUInterger)hash;
解释:如果两个对象的指针完全相同,那么两个对象相等;如果对象相等,那么hash 值也一定相等,但是hash 值相等,不能得出对象一定相等
在容器中放入可变对象的后,不应该在改变其hash 码,容器会把对象按照hash 码放入不同的箱子,如果真的要变,那么就要考虑其带来的其他隐患
编写等同性方法原则:
- 不要盲目的去检查每条数据的属性,应该根据不同的需求来制定方案
- 编写hash 方法的时候,应该采用计算速度快,碰撞几率低的算法