iOS_Runtime5_消息转发

  • 当消息接受者,未找到对应的方法实现的时候,经过一系列的方法跳转,可以让消息接受者调用其他的已实现的方法,也可以改变消息接受者,以及消息接受者调用的方法。
  • 代码示例(最终改变消息接受者,以及调用的方法):
// TestDeliverNews.h
#import <Foundation/Foundation.h>
@interface TestDeliverNews : NSObject
- (void)clearNews;
@end

// TestDeliverNews.m
#import "TestDeliverNews.h"
#import <objc/message.h>
#import "Person.h"
/*
  调用未实现的方法,进行消息转发
 */
@implementation TestDeliverNews
//  方法一
+ (BOOL)resolveInstanceMethod:(SEL)sel{
    // 消息接收者没有找到对应的方法实现的时候,会先调用此方法,可在此方法实现中动态添加新的方法
    // 返回YES表示相应selector的实现已经被找到,或者添加新方法到了类中,否则返回NO
    return YES;
}

//  方法二
- (id)forwardingTargetForSelector:(SEL)aSelector {
    //  如果方法一的返回NO,或者直接返回了YES,而没有添加方法,该方法将会被调用
    //  在这个方法中,我们可以指定一个对象作为返回值,而返回的对象可以响应(aSelector)方法
    //  注意如果返回self就会死循环
    return nil;
}

//  方法三
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    //  如果方法二的返回值为nil,则此方法(方法三)会被调用,系统会询问我们要一个合法的『类型编码(Type Encoding)』
    //  如果该方法返回 nil,则不会进入下一步,而是无法处理消息

    return [NSMethodSignature signatureWithObjCTypes:"v@:"];
}

// 方法四(1)
// 在这里进行消息转发
// 当方法四(1)被实现之后,方法四(2)将不会被调用
- (void)forwardInvocation:(NSInvocation *)anInvocation {
    // 在这里可以改变方法选择器
    [anInvocation setSelector:@selector(sayHello)];
    // 改变方法选择器后,需要指定消息的接收者

    // 这里指定Person的对象为消息的接受者
    Person *per = objc_msgSend(objc_msgSend(objc_getClass("Person"), sel_registerName("alloc")), sel_registerName("init"));
    [anInvocation invokeWithTarget:per];
    // 注意:anInvocation需要先改变方法选择器,然后再指定消息的接受者
}
// 方法四(2)
// 如果没有实现消息转发方法:方法四(1) ,则调用此方法
- (void)doesNotRecognizeSelector:(SEL)aSelector {
    NSLog(@"unresolved method :%@", NSStringFromSelector(aSelector));
}

调用示例:

TestDeliverNews *test = [[TestDeliverNews alloc]init];
[test clearNews];

类型编码(Type Encoding)

iOS_Runtime1_消息发送机制

iOS_Runtime2_方法交换

iOS_Runtime3_动态添加方法

iOS_Runtime4_动态添加属性

iOS_Runtime6_字典转化为模型应用


代码地址:
https://github.com/FlyingKuiKui/RunTime.git

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值