runtime选择器和消息转发处理

方法相关的操作函数

// 调用指定方法的实现
id method_invoke ( id receiver, Method m, ... );

// 调用返回一个数据结构的方法的实现
void method_invoke_stret ( id receiver, Method m, ... );

// 获取方法名
SEL method_getName ( Method m );

// 返回方法的实现
IMP method_getImplementation ( Method m );

// 获取描述方法参数和返回值类型的字符串
const char * method_getTypeEncoding ( Method m );

// 获取方法的返回值类型的字符串
char * method_copyReturnType ( Method m );

// 获取方法的指定位置参数的类型字符串
char * method_copyArgumentType ( Method m, unsigned int index );

// 通过引用返回方法的返回值类型字符串
void method_getReturnType ( Method m, char *dst, size_t dst_len );

// 返回方法的参数的个数
unsigned int method_getNumberOfArguments ( Method m );

// 通过引用返回方法指定位置参数的类型字符串
void method_getArgumentType ( Method m, unsigned int index, char *dst, size_t dst_len );

// 返回指定方法的方法描述结构体
struct objc_method_description * method_getDescription ( Method m );

// 设置方法的实现
IMP method_setImplementation ( Method m, IMP imp );

// 交换两个方法的实现
void method_exchangeImplementations ( Method m1, Method m2 );

方法选择器函数

// 返回给定选择器指定的方法的名称
const char * sel_getName ( SEL sel );

// 在Objective-C Runtime系统中注册一个方法,将方法名映射到一个选择器,并返回这个选择器
SEL sel_registerName ( const char *str );

// 在Objective-C Runtime系统中注册一个方法
SEL sel_getUid ( const char *str );

// 比较两个选择器
BOOL sel_isEqual ( SEL lhs, SEL rhs );

消息转发

//
//  MethodTool.h
//  RunTimeExample
//
//  Created by kobe on 16/2/25.
//  Copyright (c) 2016年 kobe. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface MethodTool : NSObject

-(void)method2;

@end
//
//  MethodTool.m
//  RunTimeExample
//
//  Created by kobe on 16/2/25.
//  Copyright (c) 2016年 kobe. All rights reserved.
//

#import "MethodTool.h"

@interface MethodTool()


@end


@implementation MethodTool


-(void)method2{

    NSLog(@"消息工具处理中");
     NSLog(@"%@, %p", self, _cmd);
}

@end

首先执行的是动态方法解析

//
//  RuntimeMethod.m
//  RunTimeExample
//
//  Created by kobe on 16/2/25.
//  Copyright (c) 2016年 kobe. All rights reserved.
//

#import "RuntimeMethod.h"
#import "MethodTool.h"
#import <objc/runtime.h>

@interface RuntimeMethod()

{
    MethodTool *methodTool;

}

@end

@implementation RuntimeMethod

+(instancetype)object{
    return [[self alloc]init];
}

-(instancetype)init{

    self=[super init];
    if (self!=nil) {
        methodTool=[[MethodTool alloc]init];
    }
    return self;
}

-(void)sendMessageOne{

    [self performSelector:@selector(method2)];
}

//转发消息的方法
void sendMessage(id self, SEL _cmd){

    NSLog(@"动态解析方法处理完成");
    //NSLog(@"%@,%p",self,_cmd);
}

//动态方法解析,对象在接受到未知消息的时候,首先调用这个方法(类的实例方法)
+(BOOL)resolveInstanceMethod:(SEL)sel{

    NSLog(@"动态解析方法");
    //获取SEL
    NSString *selectorString=NSStringFromSelector(sel);
    if ([selectorString isEqualToString:@"method9"]) {
        //为当前类添加一个消息转发的方法
        class_addMethod(self.class, @selector(sendMessageOne), (IMP)sendMessage,"v@:");
    }
    return [super resolveInstanceMethod:sel];
}
@end

如果动态解析方法没处理,就执行备用消息处理
//备用消息接受

-(id)forwardingTargetForSelector:(SEL)aSelector{

    NSLog(@"备用消息接受者");
    NSString *selectorString = NSStringFromSelector(aSelector);

    if ([selectorString isEqualToString:@"method9"]) {
        return methodTool;
    }
    return [super forwardingTargetForSelector:aSelector];
}

如果备用消息没处理就执行完整消息处理

//方法签名
-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{

    NSMethodSignature *signature=[super methodSignatureForSelector:aSelector];
    if (!signature) {
        if ([MethodTool instancesRespondToSelector:aSelector]) {
            signature=[MethodTool instanceMethodSignatureForSelector:aSelector];
        }
    }
    return signature;
}

//完整消息的转发
-(void)forwardInvocation:(NSInvocation *)anInvocation{
    NSLog(@"完整消息转发");
    if ([MethodTool instancesRespondToSelector:anInvocation.selector]) {
        [anInvocation invokeWithTarget:methodTool];
    }
}

使用方法

- (void)viewDidLoad {
    [super viewDidLoad];

    //消息转发处理
    RuntimeMethod *runtimeMethod=[[RuntimeMethod alloc]init];
    [runtimeMethod performSelector:@selector(sendMessageOne)];
}

以上所有的方法名称必须是类里面拥有的,不然这些转发的消息处理函数就会报错

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值