本文由 简悦 SimpRead 转码, 原文地址 roadmap.isylar.com

1. 成员变量 实例变量 属性

图中的 Member Variable declarations 翻译过来就是成员变量的声明

类: Class (description/template for an object)
实例: Instance (manifestation of a class)
消息: Message (sent to object to make it act)
方法: Method (code invoked by a Message)
实例变量: Instance Variable (object-specific storage)
超类/子类: Superclass/Subclass (Inheritance)
协议:  Protocol (non-class-specific methods)


从给出的英文说明,可以看出:实例(Instance)是针对 类(class)而言的。实例是指类的声明;由此推理,实例变量(Instance Variable) 是指由类声明的对象

严格说来,上图中的 int count; 是一个成员变量。而 NSString name; 是一个实例变量(NSString 是一个类). 至于 id data 应该属于成员变量还是实例变量呢? 因为 id 是 OC 特有的类型。从本质上讲, id 等同于 (void *)。 所以 id data 应属于 实例变量。

成员变量:通常是指向对象或是基础类型(int, float)的简单指针。可以在. h 或是 .m 文件中声明:

实例变量:是成员变量的一种,实例是针对类而言的,是指对类的声明;由此推理,实例变量是指由类声明的对象。

2. @synthesizer

@synthesize 语句只能被用在 @implementation 代码段中,@synthesize 的作用就是让编译器为你自动生成 setter 与 getter 方法,@synthesize 还有一个作用,可以指定与属性对应的实例变量,例如 @synthesize myButton = xxx;那么 self.myButton 其实是操作的实例变量 xxx,而不是_myButton 了。

如果. m 文件中写了 @synthesize myButton; 那么生成的实例变量就是 myButton;如果没写 @synthesize myButton; 那么生成的实例变量就是_myButton。

3. @property

Objective-C2.0 中的新语法:Properties它帮我们自动生成 getter 和 setter

@property声明属性,其实是做了三件事

  • .h: 声明了 getter 和 setter 方法;

  • .h: 声明了实例变量 (默认: 下划线 + 属性名);

  • .m: 实现了 getter 和 setter 方法。

    @property = Ivar + getter + setter

4. property 关键字

读写权限

  • readonly
  • readwrite √默认关键字

引用计数

  • retain / strong

    都是强引用,除了某些情况下不一样,比如修饰 block,其他的时候也是可以通用的。

    (external 为 Block 外属性)

  • weak / assign

    assign:

    修饰基本数据类型,如 int, bool 等

    修饰对象类型时,不改变其引用计数

    会产生悬垂指针:仍然指向内存地址,如果没覆盖后还调动变量就会 crash

    weak:

    不改变修饰对象的引用计数

    所指对象在释放之后会自动设置为 nil

  • copy

name浅拷贝深拷贝
新内存空间不分配分配
引用计数影响不影响
源对象类型拷贝方式目标对象类型拷贝类型
mutable 对象copy不可变深拷贝
mutable 对象mutableCopy可变深拷贝
immutable 对象copy不可变浅拷贝
immutable 对象mutableCopy可变深拷贝

原子性

  • atomic √默认关键字
  • nonatomic

atomic保证赋值获取是线程安全,是对成员属性的直接的获取安全,并不代表操作和访问安全.

atomic 是自旋锁,即当上一线程没有执行完毕(被锁住),下一线程会一直等待(不会进入睡眠状态),当上一线程执行完毕,下一线程立即执行。他区别于互斥锁,互斥锁在等待的时候,会进入睡眠状态,当上一个线程执行完毕,睡眠状态就会被唤醒,然后再执行。

比如 atomic 修饰的是一个数组, 对数组赋值获取是安全的,但是对数组进行操作 (添加对象,移除对象) 是不保证线程不安全的. 而且采用atomic消耗比较大

array = [[NSArray alloc]init];    //安全
[array addobject:obj];    //也会存在不安全


补充介绍 weak关键字

实现原理 weak修饰时,runtime会维护一个hash表(也称为weak表), 用于存储对象的所有weak指针,hash表的key是该对象的地址,valueweak指针的地址(这个地址的值是所指对象的地址)数组。(备注strong是通过runtime维护的一个自动引用计数表)

weak的实现原理总结:

  1. 初始化时,runtime会调用objc_initWeak函数,初始化一个新的weak指针指向对象地址;
  2. 添加引用时,objc_initWeak函数会调用objc_storeWeak函数,objc_storeWeak的作用是更新指针指向,创建对应的弱引用表(hash 表)
  3. 释放时,调用clearDeallocating函数。clearDeallocating函数首先根据对象地址获取weak指针地址的数组,然后遍历这个数组把其中指向空对象的指针设为nil,最后把这个指针从weak表中删除, 最后清理对象的记录。

关于 ARC 下,不显示指定属性关键字时,默认关键字: 1. 基本数据类型:atomic readwrite assign 2. 普通 OC 对象: atomic readwrite strong