文档章节

objc运行时,方法交换 模板示例

quntion
 quntion
发布于 2016/02/09 20:43
字数 776
阅读 137
收藏 0

模板代码:

    

/**
 1. 将 AFN 中的两个静态函数复制过来
 2. 添加运行时的头文件
 3. 在 +load 方法中交换方法,是在类被添加到运行时的时候,被调用,而且只会被执行一次
 
 内联函数,会在编译的时候,将整个函数体,复制到调用函数的位置,不会创建单独的函数
 通常适合非常短小的函数,内联函数在 C++ 中使用的非常多!
 */
static inline void af_swizzleSelector(Class theClass, SEL originalSelector, SEL swizzledSelector) {
    // 1. 从一个类中获取到原始的方法,例如 setImage:
    Method originalMethod = class_getInstanceMethod(theClass, originalSelector);
    // 2. 从一个类中获取到交换的方法,例如 me_setImage:
    // 使用此函数之前,需要添加方法 me_setImage: 添加到 UIImageView 的 class 上
    Method swizzledMethod = class_getInstanceMethod(theClass, swizzledSelector);
    
    // 3. 交换方法的实现
    method_exchangeImplementations(originalMethod, swizzledMethod);
}

static inline BOOL af_addMethod(Class theClass, SEL selector, Method method) {
    // 给指定的类,添加一个方法
    return class_addMethod(theClass, selector,  method_getImplementation(method),  method_getTypeEncoding(method));
}


使用时只要将代码拷贝到做方法交换的地方在load中使用即可。

代码示例:

    

//
//  ViewController.m
//  06-交换方法
//
//  Created by xxxx on 16/1/14.
//  Copyright © 2016年 xxxx. All rights reserved.
//

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

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@end

@implementation ViewController

/**
 1. 将 AFN 中的两个静态函数复制过来
 2. 添加运行时的头文件
 3. 在 +load 方法中交换方法,是在类被添加到运行时的时候,被调用,而且只会被执行一次
 
 内联函数,会在编译的时候,将整个函数体,复制到调用函数的位置,不会创建单独的函数
 通常适合非常短小的函数,内联函数在 C++ 中使用的非常多!
 */
static inline void af_swizzleSelector(Class theClass, SEL originalSelector, SEL swizzledSelector) {
    // 1. 从一个类中获取到原始的方法,例如 setImage:
    Method originalMethod = class_getInstanceMethod(theClass, originalSelector);
    // 2. 从一个类中获取到交换的方法,例如 me_setImage:
    // 使用此函数之前,需要添加方法 me_setImage: 添加到 UIImageView 的 class 上
    Method swizzledMethod = class_getInstanceMethod(theClass, swizzledSelector);
    
    // 3. 交换方法的实现
    method_exchangeImplementations(originalMethod, swizzledMethod);
}

static inline BOOL af_addMethod(Class theClass, SEL selector, Method method) {
    // 给指定的类,添加一个方法
    return class_addMethod(theClass, selector,  method_getImplementation(method),  method_getTypeEncoding(method));
}

+ (void)load {
    
    // 交换方法有一个特点,一旦交换,全局变化!
    // see: http://nshipster.cn/swift-objc-runtime/
    // 1. 从当前类中 - 获得准备交叉的方法
    Method swizzledMethod = class_getInstanceMethod([self class], @selector(me_setImage:));
    
    // 2. 将方法添加到 `UIImageView` 的类上
    if (af_addMethod([UIImageView class], @selector(me_setImage:), swizzledMethod)) {
        // 3. 方法添加成功,交换 UIImageView 类中的对象方法
        af_swizzleSelector([UIImageView class], @selector(setImage:), @selector(me_setImage:));
    }
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 目标 -> 拦截 UIImageView 的 setImage: 方法
    self.imageView.image = [UIImage imageNamed:@"tabbar_compose_camera"];
}

// 方法一旦交换完成,代码本身虽然还在 viewController 中,但是已经被添加到了 UIImageView 上,
// 1> 名字被改成了 setImage:
// 2> 原有的 setImage: 被改成了 me_setImage:
// 注意:ViewController 自己千万不要调用 hm_serImage:,否则死循环!
- (void)me_setImage:(UIImage *)image {
    // self == UIImageView
    NSLog(@"%@ %@", image, self);
    
    // 调用系统的 setImage:
    [self me_setImage:image];
}

@end



© 著作权归作者所有

quntion
粉丝 4
博文 13
码字总数 5430
作品 0
海淀
私信 提问
iOS开发 Runtime原理及使用(最后面试题详解)

runtime简介 因为Objc是一门动态语言,所以它总是想办法把一些决定工作从编译连接推迟到运行时。也就是说只有编译器是不够的,还需要一个运行时系统 (runtime system) 来执行编译后的代码。这...

_小迷糊
2018/12/10
0
0
iOS进阶之runtime作用

图片来源于网络 前言 Runtime基本是用C和汇编写的,可见苹果为了动态系统的高效而作出的努力。你可以在这里下到苹果维护的开源代码。苹果和GNU各自维护一个开源的runtime版本,这两个版本之间...

DWade_Coding
2017/10/09
0
0
iOS运行时Runtime浅析

版权声明:本文为博主原创文章,欢迎分享到其它技术社区,分享请标明出处: https://blog.csdn.net/CHENYUFENG1991/article/details/51931320 运行时是iOS中一个很重要的概念,iOS运行过程中...

乞力马扎罗的雪CYF
2016/07/17
0
0
iOS 模块详解—「Runtime面试、工作」看我就 🐒 了 ^_^.

iOS 模块详解—「Runtime面试、工作」看我就 🐒 了 ^_^. 转载:原地址https://www.jianshu.com/p/19f280afcb24 引导 对于从事 iOS 开发人员来说,所有的人都会答出「 Runtime 是运行时 」,...

法斗斗
2018/04/20
0
0
runtime应用场景

一、runtime简介 RunTime简称运行时。OC就是,也就是在运行时候的一些机制,其中最主要的是消息机制。对于C语言,。对于OC的函数,属于,在编译的时候并不能决定真正调用哪个函数,只有在真正...

刀客445
2016/05/20
8
0

没有更多内容

加载失败,请刷新页面

加载更多

java 面试知识点笔记(十一)多线程与并发-原理 中篇

自适应自旋锁:(java6引入,jvm对锁的预测会越来越精准,jvm也会越来越聪明) 自选次数不再固定 由前一次在同一个锁上的自旋时间及锁拥有者的状态来决定(如果在同一个锁对象上自旋等待刚刚成...

断风格男丶
19分钟前
1
0
Rainbond 5.1.4发布,复杂微服务架构整体升级和回滚

Rainbond 5.1.4发布, 复杂微服务架构整体升级和回滚 今天为大家带来Rainbond 5.1系列第四个更新版本,本次版本更新的主要内容是复杂微服务架构应用整体升级和回滚,能实现复杂微服务架构的持...

好雨云帮
20分钟前
1
0
selenium Python定位元素和相关事件

场景 通过使用selenium python的API能够很好的定位html中的元素,并指挥鼠标进行点击。 定位元素 find_element_by_*方法 find_element_by_id(id_) : html标签中的id确定标签 find_element_b...

亚林瓜子
26分钟前
0
0
apache隐藏版本信息及设置网页缓存

实战:源码编译安装apache及调优技巧 实战环境: 生产环境中,部署了apache之后,我们应该从安全还是性能角度,在apache服务上线之前,对其做诸多的优化调试才行。 技巧1: 安装apache屏蔽a...

寰宇01
40分钟前
1
0
百度小程序第三方接入图片上传demo

代码是基于ThinkPHP 3.2的,其他语言请自行实现,PHP版本为5.6 /*** 图片上传* @Author Qianlong <87498106@qq.com>* @PersonSite http://dev.21ds.cn/*/ public function onlyUpl......

千龍
42分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部