美文网首页
runtime之动态添加方法

runtime之动态添加方法

作者: Just丶Go | 来源:发表于2018-03-06 13:58 被阅读0次
  实际上是解释消息传递的机制中的一个动态解析过程(新增)

需求:runtime 动态添加方法处理调用一个未实现的方法 和 去除报错。

案例代码

//
//  UsrModel.h
//  Runtime_testing
//
//  Created by ZTL_Sui on 2018/2/28.
//  Copyright © 2018年 ZTL_Sui. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface UsrModel : NSObject
- (NSString *)run:(NSNumber *)meter;
- (NSNumber *)eat;
@end

IMP

//
//  UsrModel.m
//  Runtime_testing
//
//  Created by ZTL_Sui on 2018/2/28.
//  Copyright © 2018年 ZTL_Sui. All rights reserved.
//

#import "UsrModel.h"
#import <objc/runtime.h>

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wincomplete-implementation"
@implementation UsrModel
#pragma clang diagnostie pop

/// 此处方法可以改写为OC实例方法
NSString * _c_method (id self, SEL _cmd, NSNumber *meter)
{
    NSLog(@"跑了 %@米", meter);
    return @"333";
}
/**
 * OC底层是通过消息机制来进行消息发送的,而不是静态语言的函数调用(改)。
 * 向一个对象发送消息的处理流程
 -->对象接收到消息
 -->查看缓存中是否有匹配的方法,如果有则响应,否则继续
 -->查看对象的类对象的方法列表(method list)中是否有匹配方法,如果有则响应,否则继续
 -->查看对象的父类的缓存和方法列表中是否有匹配方法,如果有则响应,没有继续
 -->进入动态解析 +(BOOL)resolveInstanceMethod:(SEL)sel;+(BOOL)resolveClassMethod:(SEL)sel,如果有指定的动态解析方法则响应,否则继续<PS:resolveInstanceMethod解析对象方法;resolveClassMethod解析类方法>
 -->进入消息重定向 -(id)forwardingTargetForSelector:(SEL)aSelector;如果有指定消息接收对象则响应,否则继续
 -->开始消息转发 -(void)forwardInvocation:(NSInvocation *)anInvocation;如果有指定转发对象则响应,否则抛出异常
 *
 **/
/// 下面我们着重实现动态解析的过程
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
    if (sel == NSSelectorFromString(@"run:"))
    {
        /// type: 解释 "s@:@" \
        /// s@:表示函数返回值;其中s表示返回字符串类型,v表示void,i表示int,以此类推;
        ///返回值类型后面的@表示参数,有几个参数就有几个@;
        class_addMethod(self, sel, (IMP)_c_method, "s@:@");

        return YES;
    }

    return [super resolveInstanceMethod:sel];
}

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
    SEL name = [anInvocation selector];
    NSLog(@" >> forwardInvocation for selector %@", NSStringFromSelector(name));
    
    UsrModel * proxy = [[UsrModel alloc] init];
    if ([proxy respondsToSelector:name]) {
        [anInvocation invokeWithTarget:proxy];
    }
    else {
        [super forwardInvocation:anInvocation];
    }
}

+(BOOL)resolveClassMethod:(SEL)name
{
    NSLog(@" >> Class resolving %@", NSStringFromSelector(name));
    return [super resolveClassMethod:name];
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    return [UsrModel instanceMethodSignatureForSelector:aSelector];
}

-(void)Bar
{
    NSLog(@" >> Bar() in Foo.");
}
- (NSNumber *)eat
{
    NSLog(@"我吃了");
    return @43;
}

@end

代码中已附个人整理。
此份总结参考于各个大牛的经验分享。在此,谢谢各位大牛的分享~
最后 附demo: https://github.com/304164084/runtime_demo

相关文章

  • runtime的理解(二)

    主要内容 利用 runtime 交换方法 利用 runtime 动态添加方法 利用 runtime 动态添加属性 ...

  • runtime

    runtime交换方法 动态添加方法

  • 自己实现OC的KVO

    Runtime系列文章在这:Runtime介绍---术语介绍Runtime应用--动态添加方法Runtime应用-...

  • runtime和oc内存区域(2018-04-02)

    runtime常用的几个方法: 交换方法 动态添加属性 动态添加方法 1.交换方法 class_getClassM...

  • IOSRunTime_动态添加方法

    利用RunTime运行时,动态添加一个方法 动态添加方法,首先实现这个resolveInstanceMethod ...

  • runTime之--动态添加方法

    Runtime运行时之--动态添加方法 - OC都是懒加载机制、只要方法实现了,就会马上添加到方法列表List中-...

  • runtime相关

    修改系统方法 动态添加方法 动态给系统类添加属性(给分类添加属性) runtime+kvc 转换模型

  • runtime简单使用之动态添加方法

    一, runtime的动态添加方法功能 1, 关于runtime动态添加方法,我们以一个经典的面试题展开对其的研究...

  • runtime之动态添加方法

    如果一个类接收到一个没有实现的实例方法,就会进到下面这个方法里+(BOOL)resolveInstanceMeth...

  • runtime之动态添加方法

    需求:runtime 动态添加方法处理调用一个未实现的方法 和 去除报错。 案例代码 IMP 代码中已附个人整理。...

网友评论

      本文标题:runtime之动态添加方法

      本文链接:https://www.haomeiwen.com/subject/sgwlfftx.html