登录 立即注册
金钱:

Code4App-iOS开发-iOS 开源代码库-iOS代码实例搜索-iOS特效示例-iOS代码例子下载-Code4App.com

从iOS点语法引发的一番思考 [复制链接]

2017-1-11 12:22
Torr 阅读:240 评论:0 赞:0
Tag:  

当我们去点一个属性的时候,我们知道其实是调用了属性的setter或者getter方法。那么,用点调用一个方法会发生什么?

这时候系统并不会崩溃,而只是报一个警告(Property access result unused)。

现在我改成用中括号正常调用方法,可是由于粗心没有在.m中写方法的实现,会发生什么呢?

OC是一门动态编程语言。

调用saySomething这个方法。如果这个方法只是在.h中声明了,而没有在.m中实现。那么我们编译程序不会出现问题(Build Success),只有当运行程序的时候,才会直接崩溃(unrecognized selector sent to instance 0x60000000e8d0)

这是因为在编译阶段,编译器并不知道saySomething要执行那段代码,这个时候[people saySomething]会转换为objc_msgSend(people, "someThing"),就是说给people以selector的形式发送someThing这个消息。当真正运行的时候,才会去people的内存中寻找someThing的地址,这时候找不到才会造成崩溃。

那么,有没有办法说可以不在.m中实现somtThing,而又不让程序崩溃呢?

有!所谓 动态语言,就是一类在运行时可以改变其结构的语言:例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化。

想要程序不崩溃,我们有三次机会去拯救它。这个就是 消息转发机制的三个步骤 :

第一步:动态方法解析

下图可以看到,我没有实现saySomething的方法,程序运行成功。实际上是调了doSomething这个方法。

我们这里的saySomething是对象方法,如果是类方法的话,对应的是resolveClassMethod:

第二步:备用接收者

如果我们浪费了第一次机会不用,还有第二次机会拯救工程:把这个消息转给别人,让别人替我处理!

下图可以看到,我没有实现run方法,而是交给了_dog去处理这个消息。在Dog.m中,我实现了的run方法被调用了!

第三步:完整转发消息

如果我们连第二次机会都浪费了,那么还有最后一次机会补救。在完整转发消息这一步中,我们把消息封装到NSInvocation对象中,并把它发给一个能够响应消息的对象。

观察消息转发机制的后两步,其实都已经不是people在处理消息了,而是交给了别人。但是在外面看,我们是调用了[people run] 和 [people eat] 。通过这种方式可以将本来对象A要做的事交给B或C来做。

 

 

来自:https://segmentfault.com/a/1190000008047643

分享到:
我来说两句
您需要登录后才可以评论 登录 | 立即注册
所有评论(0)
关闭

每日头条

通过邮件订阅最新 Code4App 信息
上一条 /4 下一条
联系我们
关闭
合作电话:
13802416937
Email:
435399051@qq.com
商务市场合作/投稿
问题反馈及帮助
联系我们

广告投放| Github|申请友链|手机版|Code4App ( 粤ICP备15117877号-1 )

返回顶部