聊天emem培养基是什么意思

&nbsp>&nbsp
&nbsp>&nbsp
ios教程 &nbsp>&nbsp
iOS 消息转发流程
摘要:片头在Objective-C中,可以向任意一个对象发送任意一条消息,即使该方法在编译期并没有相应的实现。例如在rev类中并没有实现willCrash方法,仍向对象rev发送该消息[revperformSelector:@selector(willCrash)]或objc_msgSend(rev,@selector(willCrash))当程序执行到上面的代码时,若不作任何的处理,最终会导致程序被强制中止,抛出unrecognizedselectorsenttoinstance
在Objective-C中,可以向任意一个对象发送任意一条消息,即使该方法在编译期并没有相应的实现。例如在rev类中并没有实现willCrash方法,仍向对象rev发送该消息
[rev performSelector:@selector(willCrash)]
objc_msgSend(rev,@selector(willCrash))
当程序执行到上面的代码时,若不作任何的处理,最终会导致程序被强制中止,抛出 unrecognized selector sent to instance。
考虑到这种情况,苹果提供了一种机制,在程序运行时,从向对象rev发送不能被响应的消息willCrash,到程序崩溃的过程中,可以让编程者有机会处理这条消息,使得程序正常运行下去,称它为消息转发机制。
主要由NSObject的下面三个方法来实现整个转发过程:1、+resolveInstanceMethod:(或+resolveClassMethod:)2、-forwardingTargetForSelector:3、-(void)forwardInvocation:(NSInvocation *)anInvocation
比如有一个Person类,类里面只实现了-run方法
// Person.h@interface Person
: NSObject- (void)@end // Person.m@implememtation- (void)run {
NSLog(@&run&);}@end
若向Person类的对象发送一条没有实现的消息,比如fly
Person *man = [Person new];[man performSelector:@selector(fly)]; // fly并没有相应实现
下面在崩溃之前,来解决这个异常。
1、动态方法解析
首先,在Person类重写-resolveInstanceMethod:方法,在程序挂掉之前可以看到该方法被回调
+ (BOOL)resolveInstanceMethod:(SEL)sel {
// do something ..
return didR}
首先无论该方法return YES或者NO,都不影响转发行为。虽然不清楚return的作用,但是根据我的观察确实是不影响
只要在return之前实现了动态实现了fly方法(通常是通过runtime的库函数class_addMethod()),系统会通过(fly)找到对应IMP指针并调用,解决崩溃问题
@implememtation+ (BOOL)resolveInstanceMethod:(SEL)sel {
if (sel==(fly)) NSLog(@&try fly&);
// 为fly方法添加实现
Method impMethod = class_getInstanceMethod(self, @selector(addTwoWings));
class_addMethod(self, @selector(fly), method_getImplementation(impMethod), method_getTypeEncoding(impMethod));
// return YES NO都一样
return YES;}- (void)addTwoWings {
NSLog(@&add two wings and i will fly&);}@end
@implememtation+ (BOOL)resolveInstanceMethod:(SEL)sel {
if ((fly)) NSLog(@&try fly&);
class_addMethod(self, @selector(fly), (IMP)c_addTwoWings, &:&);
return YES;}void c_addTwoWings(id self,SEL_cmd) {
printf(&add two wings and i will fly&);}@end
[man performSelector:@selector(fly)];// 控制台打印 try fly// 控制台打印 add two wings and i will fly
若fly方法仍然没有实现,则进入消息转发
2、消息转发
(1)动态方法解析返回NO,Person类的方法-forwardingTargetForSelector:将被回调
- (id)forwardingTargetForSelector:(SEL)aSelector { // 可以处理该消息的对象}
若return为nil,意味着handler=self,不转发消息,后续仍然是自己来处理。
若return不为nil,则意味着告诉系统交由对象handler去处理这个消息。
(2)接着系统将在handler的类里面尝试寻找@selector(fly)对应的实现,
IMP ptr = class_getMethodImplementation([handler class], @selector(fly));
若 ptr != NULL,则调用ptr(handler,@selector),完成转发。
若 prt==NULL,进入下一步
(3)handler的methodSignatureForSelector:方法将被回调,请求返回方法签名,打包成NSInvocation对象(可以理解为确认handler是否能处理fly这个消息),即
[handler methodSignatureForSelector:@selector];
若return为nil,意味着handler实际上并不能处理fly方法,程序将会挂掉并抛出unrecognized selector sent to instance。
若return不为nil,意味着handler将要处理该方法,并进入下一步
(注意:-forwardingTargetForSelector:返回nil则回调self(Person)的methodSignatureForSelector:方法)
(4)最后的一步Person类的-(void)forwardInvocation:(NSInvocation *)anInvocation被回调,注意是Person类并不是handler的类
-(void)forwardInvocation:(NSInvocation *)anInvocation {
if ((fly)) {
// 相应处理,消息转发完成
举个常用实例:Person类重写-forwardingTargetForSelector:,把fly消息转发给Plane类对象去处理
@implememtation+ (BOOL)resolveInstanceMethod:(SEL)sel {
if ((fly)) NSLog(@&try fly&);// 没有实现-fly,那么消息将转发
return NO;}-(id)forwardingTargetForSelector:(SEL)aSelector {
Plane *plane= [Plane new];// 转发给plane对象}@end
其中Plane是另外一个类:
// - Plane.h@interface Plane : NSObject@end // - Plane.m@implememtaion Plane-(void)fly {
NSLog(@&take a plane and i will fly&);}@end
当程序运行到
Person *man = [Person new];[man performSelector:@selector(fly)]; // 控制台打印 try fly// 控制台打印 take a plane and i will fly
可以看到向man发送了fly消息,但man不能处理fly消息,而是将消息转发了给plane,让plane去处理fly消息,控制台打印了plane的fly方法的输出。
所以看起来像是这样的:
[man fly] 等价于=& [(Plane *)man fly]
假设不同的方法还会转发给不同的对象:
[man fire] 等价于=& [(FlameGun*)man fire]
这个man就厉害了,可以飞同时可以喷火。相当Person同时继承了飞机类Plane,也继承了喷火器类FlameGun。这就是消息转发的另一个作用:在Objective-C中实现多继承。
END:原创文章@夏冰茶
以上是的内容,更多
的内容,请您使用右上方搜索功能获取相关信息。
若你要投稿、删除文章请联系邮箱:zixun-group@service.aliyun.com,工作人员会在五个工作日内给你回复。
云服务器 ECS
可弹性伸缩、安全稳定、简单易用
&40.8元/月起
预测未发生的攻击
&24元/月起
为您提供0门槛上云实践机会
你可能还喜欢
你可能感兴趣
阿里云教程中心为您免费提供
iOS 消息转发流程相关信息,包括
的信息,所有iOS 消息转发流程相关内容均不代表阿里云的意见!投稿删除文章请联系邮箱:zixun-group@service.aliyun.com,工作人员会在五个工作日内答复
售前咨询热线
服务与支持
账号与支持
关注阿里云
International一键安装桌面版,查词翻译快三倍
选择要添加的生词本
词霸Android版
牛津词典免费使用! 立刻扫码下载
牛津词典免费使用! 立刻扫码下载
创建新的生词本
i该生词本已经创建啦!
i不可以出现中文,英文,数字之外的符号哒!
i生词本名称长度不能大于24字符!
i请填写生词本名称!聊天 - 歌单 - 网易云音乐
网易云音乐多端下载
同步歌单,随时畅听320k好音乐
网易公司版权所有(C)杭州乐读科技有限公司运营:

我要回帖

更多关于 游戏王emem卡组 的文章

 

随机推荐