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

成功了!

标准消息转发 <待续...>

 

posted @ 2015-04-26 18:16  花园晓雨  阅读(134)  评论(0编辑  收藏  举报