Runtime总结笔记`属性`

文章为原创,转载请注明出处

对象(Object) & 消息传递(Messaging)

  • 对象:基本构造单元,开发者可以用来存储并传递消息
  • 消息传递:在对象间传递数据并执行任务的过程叫“消息传递”

属性

  1. 定义: 属性用于封装对象的数据,Objective-C对象将需要的数据保存为各种实例变量(ivar),实例变量一般用存取方法获得(getter & setter),通过点语法访问属性。可总结为 property = ivar + getter + setter

  2. 属性解决的问题:定义实例变量,对象布局在编译期固定,碰到实例变量会转为“偏移量”,表示变量和对象起始内存地址的距离,编译期的偏移量,在使用新的定义和旧定义链接时会出错。把实例变量当成存储偏移量的特殊变量交给类保管,类定义变了,偏移量也就变了,类定义变了存储也就变了,这就是稳固的 “程序二进制接口ABI”,这样就可以在"class-continuation"或实现文件中定义实例变量了

@Property, @synthesize和@dynamic

  • @property:使用属性封装对象里的数据,编译期自动生成存取方法,使用"点语法"访问属性,编辑器里看不到这些“合成方法”,这一过程称为"autoSynthesize"
  • @synthesize:用来指定合成的实例变量名(ivar),推荐使用"_name"语法
  • @dynamic:不自动创建实例变量,不生成存取方法,编译器访问代码时不会报错,因为在运行时去找这些代码

属性特质

  • nonatomic:非原子的,iOS开发一般使用,使用非原子的属性不具有同步锁

  • atomic:原子的,没有这个定义,属性默认是原子的(一个属性不是非原子的,那就是原子的),不能保证线程安全,有额外开销,在MacOS开发不会太影响性能

  • readwrite:读写 readonly: 只读

  • 内存管理语义:只会影响设置方法,自己编写时必须使用属性相关的特性

    1. strong:拥有关系,设置时保留新值释放旧值
    2. weak:非拥有关系,设置时不保留新值不释放旧值,属性指向的对象销毁时,属性也清空
    3. assign:和weak一样,但只用于纯量类型(CGFloat)
    4. unsafe_retained:语义与assign相同,适用于“对象类型”,对象被摧毁时,属性值不会清空
      5.copy:语义与strong相同,设置时不保留旧值,复制新值,一般有可变类型的对象都使用copy,用来保护其封装性

在对象内部直接访问实例变量

内部访问&外部访问

  • 内部访问:在读取实例变量时直接访问(ivar),在设置时用设置方法
  • 外部访问:通过属性来访问

内部访问访问"存取方法"和使用“实例变量”的区别

  1. 不经过Objective-C方法派发,直接访问实例变量更快,编译器直接访问实例变量的地址(*ivar_list)
  2. 直接访问绕过内存管理语义,不调用设置方法,在ARC下访问Copy不会将其拷贝,只会保留新值释放旧值
  3. 直接访问不会触发KVO
  4. 通过属性访问有利于排查错误,可以在存取方法里添加断点

在初始化方法中直接访问实例变量

因为子类有可能覆写属性的设置方法,所以要用实例变量来访问,要初始化的属性要是在超类里,就只能用设置方法了

惰性初始化

惰性初始化通过存取方法访问

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章