首页 Effective Objective-C 2.0-读书笔记2
文章
取消

Effective Objective-C 2.0-读书笔记2

第2章 对象、消息、运行期

  • 对象是面向对象语言编程的基本构造单元,通过其存储并传递数据;
  • 消息传递是对象之间传递数据并执行任务的过程。

第6条:理解“属性”这一概念

  • 属性(Property),用于封装对象中的数据。Objective-C对象把其所需要的数据保存为各种实例变量。实例变量通过存取方法(access method)访问。获取方法(getter)读取变量值, 设置方法(setter)写入变量值。
Q:修改类定义后必须重新编译,否则会出错(偏移量不一致) A: Objective-C 把实例变量当作一种存储偏移量所用的“特殊变量”,交由“类对象”保管。在运行期查看偏移量。 A: 尽量不要直接访问实例变量,通过存取方法来做
  • 属性编译器自动生成存取方法,用以访问给定类型中具有给定名称的变量
  • 点语法编译器自动转换为存取方法的调用,二者没有差别
  • 使用属性,编译器会1.自动编写访问属性所需的方法(自动合成)2.自动向类中添加适当类型的实例变量,以属性名前加下划线作为实例变量的名字
  • 存取方法,除了自己实现,否则编译器会实现未自己实现的方法
  • @dynamic关键字告诉编译器,不要自动创建实现属性所用的实例变量,与存取方法

属性特质

  • 原子性

    nonatomic/atomic

  • 读/写权限

    • readwrite(读写)特质的属性拥有“获取方法”与“设置方法”,由@synthesize实现,自动生成两个方法
    • readonly(只读)特质的属性仅拥有“获取方法”,只有@synthesize实现,才会合成获取方法
  • 内存管理语义

    仅影响“设置方法”,保留值?只赋值给实例变量?根据此特质决定生成的方法代码

  • assign “设置方法”只会执行针对“纯量类型”(如:CGFLoat、NSInteger等)简单赋值
  • strong 定义”拥有关系”,为属性设置新值时,设置方法会先保留新值,并释放旧值,在设置上新值
  • weak 定义“非拥有关系”,设置新值,不保留新值,也不释放旧值。同assign类似,所指对象销毁时,会被清空
  • unsafe_unretained语义与assign相同,适用于“对象类型”,表达“非拥有关系”,目标对象被摧毁,属性值不自动清空
  • copy 有strong类似,不保留新值,将其拷贝。只要实现属性所用的对象是“可变的(mutable)”,应该设置新属性值时拷贝。

  • 方法名
  • getter= 指定“获取方法”的方法名
  • setter= 指定“设置方法”的方法名

要点

  • 可以用@property语法定义对象中所封装的数据
  • 通过“特质”指定存储数据所需的正确语义
  • 在设置属性所对应的实例变量时,一定要遵从该属性所声明的语义
  • 开发iOS时应该使用nonatomic属性,因为atomic严重影响性能

第7条:在对象内部尽量直接访问实例变量

  • 在对象之外总是应该通过属性访问实例变量
  • 在对象之内建议读取实例变量时采用直接访问的形式,设置实例变量时通过属性来做
  • 直接访问实例变量速度快(直接访问保存对象实例变量的内存);不调用“设置方法”,绕过了“内存管理语义”;不会触发“KVO”通知;使用属性访问有助于排查与之相关的错误
  • 折中方案:写入实例变量使用“设置方法”来做,读取实例变量,直接访问。
  • 初始化方法中设置属性值应该直接访问实例变量,以防被子类“覆写”设置方法
  • 惰性初始化必须通过“获取方法”来访问属性,否则,实例变量永远不会初始化

要点

  • 在对象内部读取数据时,应该直接通过实例变量来读,而写入数据时,应该通过属性来写
  • 在初始化方法及dealloc方法中,应该直接通过实例变量来读写数据
  • 使用惰性初始化技术配置数据,需要通过属性来读取数据
本文由作者按照 CC BY 4.0 进行授权