Effective Objective-C 2.0_读书笔记

1.OC使用动态绑定的消息结构,在运行时才会检查对象类型
接受消息后,要执行什么代码,由运行期环境而非编译器决定
对于多态的方法,将在运行期按照虚方法表查出到底应该执行哪个函数的实现
分配在堆中的内存(eg.对象)必须直接管理,分配在栈上用于保存变量的内存在栈帧弹出时自动清理

2.多使用字面量语法创建 @表示字面量
字符串 @“1” 数值@1 数组@[@"1",@"2"] 字典@{@"age":@28}
多使用取下标操作访问数组或字典元素,如array[1]、dictionary[@"age"]

3.使用NS_ENUM 与 NS_OPTIONS 宏定义枚举类型
指明其底层数据类型,可确保枚举为所选的底层数据类型实现的
NS_ENUM 枚举间不需要相互组合
NS_OPTIONS 按位或操作来组合的枚举,各选项定义为2的幂
在处理枚举类型的switch语句中不要实现default分支

//预定义将源代码中的ANIMATION_DURATION替换为 0.3​
#define ANIMATION_DURATION 0.3​
//这样声明的变量带有类型信息,描述了常量的含义
​static const NSTimeInterval kAnimationDuration = 0.3;

常见关键字
const 声明只读变量,表示将对象转换成一个常量,若试图修改由const 修饰的变量,编译器会报错
static 声明静态变量,意味着该变量仅在定义此变量的.m文件中可见
extern 声明变量会出现在全局符号表中,其他文件可见
typedef 用以给数据类型取别名
union 声明共用数据类型
volatile 说明变量在程序执行中可被隐含地改变

4.向前声明
在A中引用B,在A的头文件中写 @class B;实现文件中再#import "B.h"

5.对象 — 基本构造单元
@property = ivar + getter + setter;
除了生成方法代码 getter、setter 之外,编译器还要自动向类中添加适当类型的实例变量,并且在属性名前面加下划线,以此作为实例变量的名字。
通过对象,存储并传递数据,在对象之间传递数据并执行任务叫做消息传递
将所需数据保存为各种实例变量,属性用于封装对象中的数据
@synthesize 关键字用来指定实例变量的名字
@dynamic 关键字告诉编译器不要自动创建实现属性所用的实例变量,也无需创建存取方法

6.直接访问实例变量 _firstName 不会调用其“设置方法”,不会触发KVO
访问属性 self.firstName
写入实例变量时,通过其“设置方法” self.
读取实例变量时,直接访问实例变量 _
若采用懒加载(属性不常用,且创建属性的成本较高,所以延迟加载)
必须通过读取属性 self.

7.对象等同性
== 操作比较的是两个指针本身
若想检测对象等同性,重写 isEqual:和 hash 方法

8.类族模式可将实现细节隐藏在一套简单的公共接口后面

9.在既有类中使用关联对象存放自定义数据
单纯用继承的方法扩展属性,有时可能无法创建自己所写子类
给对象关联其他对象,用键区分属性

//存取方法
void objc_setAssociatedObject(idobject,void*key,idvalue,objc_AssociationPolicypolicy);
objc_getAssociatedObject(idobject,void*key);

10.objc_msgSend
OC动态性:所有的方法在底层都是普通的C语言函数,对象收到消息之后,究竟该调用哪个方法,完全在运行期决定,也可在运行期改变
此函数会依据接收者与选择子的类型来调用适当方法
现在接收者所属的类中搜索其方法列表找到则执行找不到沿着继承体系向上查找,找到后执行;若还是找不到,执行消息转发
每个类中都有一张表格,选择子为查表时所用的键

11.消息转发 objc _msgForward


消息转发流程

12.类的方法列表会把选择子的名称映射到相关的方法实现上 SEL —> IMP

13.程序运行到断点处,开发者可向console输入命令,po 对象打印

14.每个OC对象实例都是指向某块内存数据的指针,所以声明变量时,类型后跟一个 * 字符
在运行期检视对象类型 —> 类型信息查询,可查出对象是否能响应某个选择子,是否遵从某项协议,位于类继承体系的哪一部分
每个对象结构体的首个成员是Class类的变量,定义了对象所属的类,称 isa 指针,类型信息查询中使用isa指针获取对象所属的类

15.为类提供一个全能初始化方法,其他的初始化方法都要调用它
提供类的全能初始化方法,当底层数据存储机制改变时,只需修改此代码,无需改动其他初始化方法
每个类的全能初始化方法都应调用其超类的对应方法

16.尽量创建不可变的对象
为私有方法名加前缀,将其同公共方法区分开
OC的动态性使其无法再编译时就确定哪个方法公用,哪个方法私有,要在运行时,运行期检查对象能响应的方法

17.只有发生了可使整个应用崩溃的严重错误时,才应使用异常
在出现非致命错误时,处理为让方法返回nil / 0
用NSError处理
Error domain 错误范围 、产生错误的根源
Error code 错误码
User info 用户信息
通过委托协议来传递此错误,或经“输出参数”返回给调用者

- (BOOL)doSomething:(NSError**)error;   //error是个指针,且该指针本身又指向另外一个指针​

NSError *error = nil;
Bool ret = [object doSomething:&error];
if(error){...}     //若不关注具体出错原因,直接判断ret即可if(ret){...}

18.NSCopying协议/NSMutableCopying协议
遵循这个协议,对象应该实现如下方法

-(id)copyWithZone:(NSZone*)zone
//可变版本
-(id)mutableCopyWithZone:(NSZone*)zone

对于一些不可变对象,copy直接赋予对象的引用,保证一致性,因为不重新开辟空间,节约内存;但是对于可变对象,copy将重新生成一个一模一样的对象,各改各的,防止造成数据错乱。
简单做个试验,对字符串进行copy、mutableCopy,对可变字符串进行copy、mutableCopy后,输出其地址
验证copy、mutableCopy

可变字符串与其copy指向同一块内存区域

可以发现,对于不可变对象,copy会直接赋予对象的引用,不生成新对象,而对于不可变对象,copy、mutableCopy都会生成新对象。

19.通过委托和数据源协议进行对象间通信
用 respondsToSelector: 来判断委托对象是否实现了相关方法
调用 delegate 对象中的方法时,应该把发起委托的实例也一并传入方法中

20.分类的目的在于扩展类的功能,而非封装数据

  • 向无源码的既有类中新增功能
  • 分类不支持添加属性和成员变量,勿在分类中声明属性,应把封装数据所用的全部属性都定义在主接口里
  • 若在分类中声明属性,需要将其声明为@dynamic,存取方法等到运行期再提供
  • 分类中的方法是在运行期系统将分类方法加入类,直接添加在类里面的,类似于类的固有方法
  • 将类的实现代码分散到便于管理的数个分类之中
  • 通过给分类加前缀、给分类中的方法名加前缀的方法,避免分类与分类,分类与本来的类方法覆盖

21.m 文件中的@interface 叫 class-continuation分类
将私有方法的原型、类中所遵循的不为人知的协议 在class-continuation中声明
.mm 扩展名表示编译器将此文件按Objective-C++来编译

在Objective-C中,runtime会自动调用每个类的两个方法,两个方法都只会被调用一次。

+(void)load会在类初始加载时调用
+(void)initialize惰性调用。

保证在足够早的时间点被调用,将
didFinishLaunchingWithOptions 中的第三方中的注册代码、推送初始化方法挪到+ (void)load 中

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容