Runtime 消息传递

*main.m

PersonA *personA = [[PersonA alloc]init];
[personA speechJapan];
  • PersonB.h
- (void)speechJapan;
  • PersonB.m

- (void)speechJapan{
    NSLog(@"speechJapan");
}
  • PersonA.h
- (void)speechEnglish;
- (void)speechJapan;
  • PersonA.m
- (void)speechEnglish{
    NSLog(@"speechEnglist");
}

// 此方法不是方法的实现,需要进行转化
- (void)speechNewLan{
     NSLog(@"speechNewLan");
}

// 将方法转换成方法的实现IMP
IMP convertToIMP(){
    return  class_getMethodImplementation([PersonA class], @selector(speechNewLan));
}
/* 当未找到speechJapan时,首先调用此方法,使有机会添加一个实现的方法
 如果添加了方法并且放回了Yes,则运行时系统会启用一次消息发送的过程。如果返回为NO,
 运行时系统则进入到下一步,消息转发(Message Forwarding)
 */

// 消息派发
+ (BOOL)resolveInstanceMethod:(SEL)sel{
    if (sel == @selector(speechJapan)) {
        class_addMethod(self, sel, convertToIMP(), "");
        return YES;
    }
    return NO;
}


/*实现此方法,运行时系统就会调用次方法,将消息转发给其他指定的对象,
 比如转发给PersonB的对象
 
注:只要返回的对象不是nil或self,消息发送的整个过程就会启动
 发送的对象变为指定返回的对象,比如PersonB。如果返回的是nil或self,则进行下一步转发操作
 */
- (id)forwardingTargetForSelector:(SEL)aSelector{
    if (aSelector == @selector(speechJapan)) {
        PersonB *pB = [[PersonB alloc] init];
        return pB;
    }
    return [super forwardingTargetForSelector:aSelector];
}

// 消息转发第二步 Mormal forwrading

/* 获取方法签名
 调用此方法获取函数的参数和返会类型,如果此方法返回nil
 Runtime则会发出doseNotRecognizeSelector: 消息挂掉程序
 如果返回一个函数签名,Runtime则会创建一个NSINvocation对象,调用ForwradInvacation:
 发送消息给对象
 */
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
    
    NSMethodSignature *sign = [[PersonB class] instanceMethodSignatureForSelector:aSelector];
    return [NSMethodSignature signatureWithObjCTypes:"v@:"];
}

// 实现消息的转发
/*
 NSInvocation 实际上是对一个消息的描述,包括selector极其参数等信息
 所以可以在此方法中修改NSInvocation对象,然后调用invokeWithTarget:消息给对象
 */
- (void)forwardInvocation:(NSInvocation *)anInvocation{
    SEL sel = anInvocation.selector;
     PersonB *pB = [[PersonB alloc] init];
    if ([pB respondsToSelector:sel]) {
        [anInvocation invokeWithTarget:pB];
    }else{
        [self doesNotRecognizeSelector:sel];
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 今天遇到了一个引人第三方崩溃的问题,崩溃的信息是-[NSURLResponse statusCode]: unre...
    AlwaysBlue阅读 1,097评论 2 2
  • iOS中类找不到方法时消息处理机制 iOS~runtime理解 一、正常的消息传递 在C等语言中,调用一个方法就是...
    lionsom_lin阅读 371评论 0 0
  • 运行时概述Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理。这样...
    redihd阅读 1,359评论 3 8
  • by Lene Nielsen The persona method has developed from bei...
    鲜核桃阅读 1,185评论 0 0
  • 有几个小故事,以前似乎看过,但今天再看仍是有启发。 最近熬夜较多,精力明显不济。看雾霾有所消散,下午便出去散步,...
    顾影之莲阅读 239评论 0 0