iOS 开发 深入浅出Runtime运行时之方法动态处理(Dynamic Method Resolution)详解

本文深入介绍了iOS开发中Runtime运行时的动态方法处理,包括如何在运行时为selector提供实现,解析`+resolveInstanceMethod:`和`+resolveClassMethod:`的使用,以及它们在消息发送过程中的作用。通过示例代码展示了动态添加方法的实现,探讨了返回值对消息转发的影响,并对源码进行了剖析。
摘要由CSDN通过智能技术生成

前言

  1. 在查看本篇博客之前请查看
    iOS 开发 深入浅出Rumtime运行时之消息发送机制详解

这里写图片描述

  1. Object-C中向一个对象发送它无法处理的消息,会出现什么情况?

    • 我们知道发送消息是通过 objc_send(id, SEL, …) 来实现的,它会首 先在对象的类对象的 cache,method list 以及父类对象的 cache, method list 中依次查找 SEL 对应 的 IMP;
    • 如果没有找到且实现了方法动态处理机制就会进行方法动态处理,如果没有实现方法动态处理机制或处理失败且实现了消息转发机制就会进入消息转发流程,否则程序 crash。
    • 也就是说如果同时供了方法动态处理和消息转发,那么方法动态处理先于消息转发,只有当方法动态处理依然无法正确方法 selector 的 实现,才会尝试进行消息转发。
    • 在前文中,我并没有详细讲解方法动态处理,因此本文将详细介绍之。

动态方法处理

Objective C 供了一种名为动态方法处理的手段,使得我们可以在运行时动态地为一个 selector 供 实现。我们只要实现 +resolveInstanceMethod: 和/或 +resolveClassMethod: 方法,并在其中为指 定的 selector 供实现即可(通过调用运行时函数 class_addMethod 来添加)。这两个方法都是 NSObject 中的类方法,其原型为:

+ (BOOL)resolveClassMethod:(SEL)name;
+ (BOOL)resolveInstanceMethod:(SEL)name;
  • 参数 name 是需要被动态方法处理的 selector;返回值文档中说是表示动态决议成功与否。
  • 不涉及消息转发的情况下,如果在该函数内为指定的 selector 供实现,无论返回 YES 还是 NO, 编译运行都是正确的;
  • 但如果在该函数内并不真正为 selector 供实现,无论返回 YES 还是 NO,运 行都会 crash,道理很简单,selector 并没有对应的实现,而又没有实现消息转发。
  • resolveInstanceMethod 是为对象方法进行决议,而 resolveClassMethod 是为类方法进行决议。

下面我们用动态方法决议手段来修改上面的代码:

//
//  Persion.m
//  Persion
//
//  Created by zhouyu on 2016/12/1.
//  Copyright © 2016年 demo. All rights reserved.
//

#import "Persion.h"
#include <objc/runtime.h>

// 运行时的动态方法处理在动态运行时添加一个dynamicMethodIMP方法去实现run方法
void dynamicMethodIMP(id self, SEL _cmd) {
    NSLog(@" >> dynamicMethodIMP called---经过动态方法处理,run方法能正常执行了: 跑步更健康");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值