Effective Objective-C 2.0 再读笔记(三)

前篇回顾:
Effective Objective-C 2.0 再读笔记(一)
Effective Objective-C 2.0 再读笔记(二)

第12条: 理解消息转发机制

消息转发机制分为两大阶段. 第一阶段先征询接收者, 所属的类, 看其能否动态添加方法, 已处理当前这个"未知的选择子"(unknown selector), 这叫做"动态方法解析"(dynamic method resolution). 第二阶段涉及"完整的消息转发机制"(full forwarding mechanism). 若果运行时系统已经把第一阶段执行完了, 那么接收者自己就无法再以动态新增方法的手段来响应包含该选择子的消息了. 此时,运行时系统会请求接收者用其他手段来处理与消息相关的方法调用. 这又细分为两小步. 首先, 请接收者看看有没有其他对象能处理这条消息. 若有, 运行时系统就会把消息传达给那个对象, 于是消息转发过程结束, 一切正常. 如果没有"备援的接收者"(replacement receiver), 则启动完整的消息转发机制, 运行时系统会把与消息有关的全部细节都封装到 NSInvocation 对象中, 再给接收者最后一次机会, 令其设法解决当前还未处理的这条消息.

动态方法解析

对象在收到无法解析的消息后, 首先将调用所属类的下列类方法:
+ (BOOL)resolveInstanceMethod:(SEL)selector
该方法的参数就是那个为止选择子, 期返回值是 Boolean 类型, 表示这个类是否能新增一个实例方法用以处理此选择子. 在继续往下执行转发机制之前, 本类有机会新增一个处理次选择子的方法. 假如尚未实现的方法不是实例方法而是类方法, 那么运行时系统就会调用另外一个方法, 该方法与"resolveInstanceMethod:"类似, 叫做"resolveClassMethod:".

备援接收者

当前接收者还有第二次机会来处理未知的选择子, 在这一步中, 运行时系统会问它能不能将当前消息传递给其他接收者来处理. 与该步骤对应的处理方法是
(id)forwardingTargetForSelector:(SEL)selector
方法参数带代表未知的选择子, 若当前接收者能找到备援对象, 则将其返回, 若找不到, 就返回 nil.

完整的消息转发

首先创建 NSInvocation 对象, 把与尚未处理的哪条消息有关的全部细节都封于其中. 此对象包含选择子, 目标, 及参数. 在触发 NSInvocation 对象时, "消息转发系统"将亲自出马, 把消息指派给目标对象. 次步骤会调用这个方法
- (void)forwardInvocation:(NSInvocation*)invocation
这个方法实现的很简单: 只需改变调用目标, 使消息在新目标上得以调用即可.

要点:

  • 若对象无法响应某个选择子, 则进入消息转发流程
  • 通过运行时的动态方法解析功能, 我们可以在需要用到某个方法时, 再将其加入到类中.
  • 对象可以把无法处理的某些选择子交给其他对象来处理
  • 经过上述的两个步骤之后, 如果还是无法处理选择子, 那就启动完整的消息转发机制

第13条: 用"方法调配技术" 调试"黑盒方法"

此方法是利用运行时系统来交换两个选择子的具体实现方法, 主要有两个步骤:

  1. 根据给定的选择从类中取出与之对应的相关方法:
    Method class_getInstanceMethod(Class aClass, SEL aSelector)
  2. 交换两个方法实现:
    void method_exchangeImplementatios(Method m1, Method m2)

要点:

  • 在运行时, 可以向类中新增或者替换选择子所对应的方法实现
  • 使用另一份实现来替换原有的方法实现, 这道工序叫做"方法调配", 开发者常用此技术向原有实现中添加新功能.
  • 一般来说, 只有在调试程序的时候才需要在运行时修改方法实现, 这种做法不宜滥用

第15条: 用前缀避免命名空间冲突

因为 OC 没有其他语言那种内置的命名空间机制. 鉴于此, 我们要在起名时设法避免潜在的命名冲突, 否则就很容易重名了. 如果发生命名冲突, 那么程序就会报错, 甚至会崩溃.
避免此问题的唯一方法就是变相实现命名空间: 为所有名称都加上适当的前缀.

  • 注意: 使用Cocoa 创建应用程序时, 苹果宣称期保留使用所有"两个字母前缀"的去啊你. 所以自定义的前缀最好应该是三个字母的.

不仅是类名, 应用程序中的所有名称都应该加上前缀. 包括类的实现文件中所使用的纯 C函数及全局变量.

要点

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

推荐阅读更多精彩内容