方法相关的操作函数
// 调用指定方法的实现
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)];
}
以上所有的方法名称必须是类里面拥有的,不然这些转发的消息处理函数就会报错