iOS&谁说我不能执行你
写完标题,我也扑通一笑.就先来对标题透一下剧吧.
"谁说我不能执行你":应该把"我"与"你"理解成OC语言中不同类的实例对象.<IT男永远不孤单,因为IT男搞的就是面向对象的编程>
是的,在今天之前,我是不相信:我能执行你.但是,现在我相信了,没想到我是如此的强大,只是我没有发现而已!
之前,我一直是这样认为的:在iOS开发中,A类的对象a,是不能去执行B类中的实例方法的.其实不是这样的.
的确,在iOS中,是没有多继承的,只有单继承.在其它语言中,很容易实现两个不同类的对象去拥有同一个方法,因为他们是多继承的,他们就好比两个男生能拥有同一个妹子一样.iOS就没那么泛滥,是很单纯的,因为只有单继承.
现实中,需求是千奇百怪的.特殊情况,需要特殊处理.有时候在iOS开发中,也需要A类的对象a去执行B类中的实例方法.为了达到这一点,先来介绍一下消息转发机制.
消息转发
其实,当向某个对象发送某个消息时,runtime system在当前和父类中都找不到对应的实现方法是,runtime system并不会立即报错误使程序崩溃,而是依次执行下列步骤:
1,动态方法
像当前类发送+ (BOOL)resolveInstanceMethod:(SEL)sel信号,检查是否动态向该类添加了方法.可进入这个博客查看:http://blog.csdn.net/haishu_zheng/article/details/12873151
2,快速消息转发
检查该类是否实现了- (id)forwardingTargetForSelector:(SEL)aSelector方法,若实现了则调用这个方法.若该方法返回值对象非nil或者分self,则向该返回对象从新发送消息.
3,标准消息转发
runtime发送- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector消息获取selector对应方法签名.返回值非空则通过- (void)forwardInvocation:(NSInvocation *)anInvocation转发消息,返回值为空则像当前对象发送doesNotRecognizeSelector:消息,程序崩溃退出.
总结:能用以上2,3方式实现消息的转发.
快速消息转发
快速消息转发的实现方法很简单,只需要重写 - (id)forwardingTargetForSelector:(SEL)aSelector 方法即可。
我来举个简单的例子,比如现有2个类:Teacher 和 Doctor,Doctor可以做手术(operate方法)。
Teacher.h
#import <Foundation/Foundation.h>
@interface Teacher : NSObject
@end
Teacher.m
#import "Teacher.h"
#import "Doctor.h"
@implementation Teacher
- (id)forwardingTargetForSelector:(SEL)aSelector {
Doctor* doctor = [[Doctor alloc] init];
if ([doctor respondsToSelector:aSelector]) {
return doctor;
}
return nil;
}
@end
Doctor.h
#import <Foundation/Foundation.h>
@interface Doctor : NSObject
- (void)operate;
@end
Doctor.m
#import "Doctor.h"
@implementation Doctor
- (void)operate; {
NSLog(@"operate");
}
@end
到这里还差一步,再弄一个分类.具体是为什么,自己想.
Teacher+DoctorMethod.h
#import "Teacher.h"
@interface Teacher (DoctorMethod)
- (void)operate;
@end
Teacher+DoctorMethod.m
#import "Teacher+DoctorMethod.h"
@implementation Teacher (DoctorMethod)
@end
ok,现在可以到main.m中了
#import <Foundation/Foundation.h>
#import "Teacher.h"
#import "Teacher+DoctorMethod.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Teacher* teacher = [[Teacher alloc] init];
[teacher operate];
}
return 0;
}
log:2015-04-26 17:45:45.134 Quichly[3304:381361] operate
成功了!
标准消息转发 <待续...>
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。