Runtime - Method Swizzling

iOS之深入解析Runtime的Method-Swizzling方法交换的妙用和底层原理 一、method-swizzling 简介 method-swizzling 的含义是方法交换,其主要作用是在运行时将一个方法的实现替换成另一个方法的实现,这就是我们常说的iOS黑魔法。 在 OC 中就是利用 method-swizzling 实现 AOP,其中 AOP(Aspect Oriented Programming,面向切面编程)是一种编程的思想,区别于OOP(面向对象编程); OOP和AOP都是一种编程的思想 OOP编程思想更加倾向于对业务模块的封装,划分出更加清晰的逻辑单元; 而AOP是面向 阅读详情

理解Method Swizzling是学习runtime机制的一个很好的机会。在此不多做整理,仅翻译由Mattt Thompson发表于nshipster的Method Swizzling一文。

Method Swizzling是改变一个selector的实际实现的技术。通过这一技术,我们可以在运行时通过修改类的分发表中selector对应的函数,来修改方法的实现。

例如,我们想跟踪在程序中每一个view controller展示给用户的次数:当然,我们可以在每个view controller的viewDidAppear中添加跟踪代码;但是这太过麻烦,需要在每个view controller中写重复的代码。创建一个子类可能是一种实现方式,但需要同时创建UIViewController, UITableViewController, UINavigationController及其它UIKit中view controller的子类,这同样会产生许多重复的代码。

这种情况下,我们就可以使用Method Swizzling,如在代码所示:

在这里,我们通过method swizzling修改了UIViewController的@selector(viewWillAppear:)对应的函数指针,使其实现指向了我们自定义的xxx_viewWillAppear的实现。这样,当UIViewController及其子类的对象调用viewWillAppear时,都会打印一条日志信息。

上面的例子很好地展示了使用method swizzling来一个类中注入一些我们新的操作。当然,还有许多场景可以使用method swizzling,在此不多举例。在此我们说说使用method swizzling需要注意的一些问题:

Swizzling应该总是在+load中执行

在Objective-C中,运行时会自动调用每个类的两个方法。+load会在类初始加载时调用,+initialize会在第一次调用类的类方法或实例方法之前被调用。这两个方法是可选的,且只有在实现了它们时才会被调用。由于method swizzling会影响到类的全局状态,因此要尽量避免在并发处理中出现竞争的情况。+load能保证在类的初始化过程中被加载,并保证这种改变应用级别的行为的一致性。相比之下,+initialize在其执行时不提供这种保证—事实上,如果在应用中没为给这个类发送消息,则它可能永远不会被调用。

Swizzling应该总是在dispatch_once中执行

与上面相同,因为swizzling会改变全局状态,所以我们需要在运行时采取一些预防措施。原子性就是这样一种措施,它确保代码只被执行一次,不管有多少个线程。GCD的dispatch_once可以确保这种行为,我们应该将其作为method swizzling的最佳实践。

选择器、方法与实现

在Objective-C中,选择器(selector)、方法(method)和实现(implementation)是运行时中一个特殊点,虽然在一般情况下,这些术语更多的是用在消息发送的过程描述中。

以下是Objective-C Runtime Reference中的对这几个术语一些描述:

  1. Selector(typedef struct objc_selector *SEL):用于在运行时中表示一个方法的名称。一个方法选择器是一个C字符串,它是在Objective-C运行时被注册的。选择器由编译器生成,并且在类被加载时由运行时自动做映射操作。
  2. Method(typedef struct objc_method *Method):在类定义中表示方法的类型
  3. Implementation(typedef id (*IMP)(id, SEL, …)):这是一个指针类型,指向方法实现函数的开始位置。这个函数使用为当前CPU架构实现的标准C调用规范。每一个参数是指向对象自身的指针(self),第二个参数是方法选择器。然后是方法的实际参数。

理解这几个术语之间的关系最好的方式是:一个类维护一个运行时可接收的消息分发表;分发表中的每个入口是一个方法(Method),其中key是一个特定名称,即选择器(SEL),其对应一个实现(IMP),即指向底层C函数的指针。

为了swizzle一个方法,我们可以在分发表中将一个方法的现有的选择器映射到不同的实现,而将该选择器对应的原始实现关联到一个新的选择器中。

调用_cmd

我们回过头来看看前面新的方法的实现代码:

咋看上去是会导致无限循环的。但令人惊奇的是,并没有出现这种情况。在swizzling的过程中,方法中的[self xxx_viewWillAppear:animated]已经被重新指定到UIViewController类的-viewWillAppear:中。在这种情况下,不会产生无限循环。不过如果我们调用的是[self viewWillAppear:animated],则会产生无限循环,因为这个方法的实现在运行时已经被重新指定为xxx_viewWillAppear:了。

注意事项

Swizzling通常被称作是一种黑魔法,容易产生不可预知的行为和无法预见的后果。虽然它不是最安全的,但如果遵从以下几点预防措施的话,还是比较安全的:

  1. 总是调用方法的原始实现(除非有更好的理由不这么做):API提供了一个输入与输出约定,但其内部实现是一个黑盒。Swizzle一个方法而不调用原始实现可能会打破私有状态底层操作,从而影响到程序的其它部分。
  2. 避免冲突:给自定义的分类方法加前缀,从而使其与所依赖的代码库不会存在命名冲突。
  3. 明白是怎么回事:简单地拷贝粘贴swizzle代码而不理解它是如何工作的,不仅危险,而且会浪费学习Objective-C运行时的机会。阅读Objective-C Runtime Reference和查看<objc/runtime.h>头文件以了解事件是如何发生的。
  4. 小心操作:无论我们对Foundation, UIKit或其它内建框架执行Swizzle操作抱有多大信心,需要知道在下一版本中许多事可能会不一样。
SoIC、CoWoS、InFO一次讲透:从2D/2.5D/3D看懂先进封装 先进封装是后摩尔时代提升芯片性能的关键路径,但面对SoIC、CoWoS、InFO这些名词,很多人容易混淆。理解它们,需从最基本的2D、2.5D、3D封装概念入手:2D是传统平房,2.5D通过硅中介层实现高密度互连,3D则让芯片直接堆叠。CoWoS作为2.5D中介层封装,已成为AI芯片与HBM高带宽存储集成的行业标准;SoIC通过铜-铜混合键合实现真正的3D堆叠,为逻辑与缓存提供极致带宽;InFO以扇出型封装兼顾成本与集成度,广泛用于移动SoC。在系统级封装(SiP)和CPO共封装光学等前沿趋势中,这些技术往 阅读详情

相关推荐

COCO数据集缺失文件补全方法

本文代码是以目标检测(object detection)和实例分割(instance segmentation)任务的标签文件为例,即文件。其他任务的标签文件内容略有不同,但是图片来源表示字段完全相同,因此代码可通用。另外如果是非2017版本COCO应该也通用。msgspec是一个高性能的序列化和验证库,支持 JSON、MessagePack、YAML 和 TOML 等多种格式。高性能:在常见协议的编码/解码中表现出色,通常比其他库快10-80倍。零成本的模式验证。

qq_46396470的博客 1992

Objective-C Runtime 运行时之四:Method Swizzling

本文转自南峰子的技术博客

altairdipper的专栏 550

linux redis7 完整的集群搭建过程

一。安装: 1.1 说明: Redis官方只提供了源码,并没有提供经过编译之后的安装包。 因此,安装Redis,要先编译、后安装。(即源码安装方式) 注意:需要联网安装 1.2 安装编译的工具: yum install gcc gcc-c++ -y 1.3 下载tar包,上传到linux服务器,解压配置环境变量 1.4 cd +解压的目录下:编译 make 注意:如果编译失败,请重新进行解压编译,...

m0_38028438的博客 719

Python笔记

一切以代码最简、性能最高为原则,宁愿空间换时间 1.前100中,对“3的倍数”的数求和 print(sum(i for i in range(0,101,3)))#对“3的倍数”的数求和 print(sum(i for i in range(0,101,2)))#对“2的倍数”的数求和 1683 2550 PS:不要求最简的话,使用while循环、for循环都可以得出结论 2.将字符串文本“¥12345.6789元”,加上千元内随机金额后,变为保留2位小数的字符串文本 import random#导入

天道哥哥的博客 6446

Vensim系统动力学建模实战:从理论到仿真优化【案例详解】

本文详细介绍了Vensim在系统动力学建模中的实战应用,从基础理论到仿真优化全面解析。通过人口增长、供应链库存优化等典型案例,展示如何利用Vensim构建动态模型并进行参数优化,帮助读者掌握系统动力学建模的核心技术与实践技巧。

weixin_29231725的博客 475

恶意代码实验3:Word宏病毒实验

只要下次打开这个word文档,就会执行以上代码,并将自身复制到Normal.dot(word文档的公共模板)和当前文档的ThisDocument中,同时改变函数名(模板中为Document_Close,当前文档为Document_Open),此时所有的word文档打开和关闭时,都将运行以上的病毒代码,可以加入适当的恶意代码,影响word的正常使用,本例中只是简单的跳出一个提示框。回答不正确三次,即可自动跳出病毒程序,但那时已经出现几十个文档。1、打开的宏编辑器如图所示,即可编写病毒代码。

qq_63949327的博客 6504

objc_msgSend method_getTypeEncoding 与 @encode

@encode: 将数据类型编码成char*(字符串)形式 https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/ObjCRuntimeGuide.pdf To assist the runtime system, the compiler

zhenganzhong_csdn的博客 2717

【ODX介绍】-5-用于Flash刷写的ODX-F文件概述

用于Flash刷写的ODX-F文件概述

「汽车电子助手」的博客 2530

ios笔记-runtime Method详解

Runtime Method 介绍:Method类型是一个objc_method结构体指针,objc_method有三个成员 typedef struct objc_method Method; struct objc_method{ SEL method_name;  //方法的名称 char *method_typesE;//参数和返回类型的描述字串 IMP  method_imp;

samuelandkevin的专栏 1848

在windows系统上使用codex出现应用程序无法正常启动(0xc0000022)的解决方案

本文主要介绍了在windows系统上使用codex出现应用程序无法正常启动(0xc0000022)的解决方案,希望能对使用codex的同学们有所帮助。 文章目录 1. 问题描述 2. 原因分析 3. 解决方案

weixin_43178406的博客 10万+

图神经网络实战(6)——使用PyTorch构建图神经网络

图数据集通常比简单的连接集合更加丰富,因为节点和边可以具有表示分数、颜色、单词等特征。包含这些额外信息在输入数据中对于生成最佳嵌入至关重要。在本节中,我们将使用 Cora 和 Facebook Page-Page 数据集,首先将它们视为表格数据集,观察香草神经网络在节点特征上的表现如何。然后,尝试在神经网络中加入拓扑信息,实现图神经网络 (Graph Neural Networks, GNN) 架构:一个同时考虑节点特征和边的简单模型。最后,我们将比较两种架构的性能。

盼小辉丶的博客 2万+

runtime typeencoding

TypeEncoding -(void)test:(int)num { NSLog(@"%d",num); } -(NSString *)test1:(NSString *)name { return name; } 这样一个test的typeencoding是个啥,创建一个Person,里面创建个test,test1函数 #import &

yokan_de_s的博客 1316

科研必备:15款顶尖AI科研工具全面分析汇总(持续更新ing)

科研必备:15款AI科研工具全面分析汇总(持续更新ing)

Code_流苏:在代码中寻诗意,在实践中觅真知 9633

Runtime Method Swizzling

原文出自:标哥的技术博客 前言在我学习runtime的method swizzling特性之前,有很多同事或者朋友经常在我耳边说起swizzling特性,一个个在我面前说这个东西千万不能用,会引起很多问题的。但是,在我学习完这一节的知识后,我终于明白其所以然。学习完swizzling特性后,我很喜欢她。她就像一把双刃剑,用好了可以带你飞,乱用则会反伤。但是,我更相信她的强大,更相信自己够能驾驭她!一

标哥 866

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Objective-C runtime机制(3)——method swizzling

方法替换,又称为method swizzling,是一个比较著名的runtime黑魔法。网上有很多的实现,我们这里直接讲最正规的实现方式以及其背后的原理。 Method Swizzling 在进行方法替换前,我们要考虑两种情况: 要替换的方法在target class中有实现 要替换的方法在target class中没有实现,而是在其父类中实现 对于第一种情况,很简单,我们直接调用me...

无忘无往 2174

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

OC学习Runtime之Method swizzling

坚持 成长 每日一篇OC的一些黑魔法除了关联对象(associated objects)还有一个比较争议的方法交换(Method swizzling)Method swizzling指的是改变一个已存在的选择器对应的实现的过程,它依赖于Objectvie-C中方法的调用能够在运行时进改变——通过改变类的调度表(dispatch table)中选择器到最终函数间的映射关系。这个黑魔法我们在之前其实已经

chirs的专栏 671

iOS runtime探究(四): 从runtiem开始实践Category添加属性与黑魔法method swizzling

你要知道的runtime都在这里转载请注明出处 http://www.jianshu.com/p/e2c0c67d39ed本文主要讲解runtime相关知识,从原理到实践,由于包含内容过多分为以下五篇文章详细讲解,可自行选择需要了解的方向: 从runtime开始: 理解面向对象的类到面向过程的结构体 从runtime开始: 深入理解OC消息转发机制 从runtime开始: 理解OC的属性proper

什么都不会的小菜鸟 2617

iOS运行时以及HOOK的理解:runtime和method swizzling

iOS运行时以及HOOK的理解:runtime和method swizzling

骑着蜗牛找马儿 1847

ETNavBarTransparent源码分析:学习Runtime与Method Swizzling的高级应用

想要为iOS应用添加丝滑的导航栏透明过渡效果吗?ETNavBarTransparent是一个优秀的开源库,它巧妙运用Runtime运行时机制和Method Swizzling方法交换技术,实现了导航栏透明度的平滑过渡。本文将深入分析这个库的核心实现,帮助开发者掌握iOS高级编程技巧。 ETNavBarTransparent是一个专门处理iOS导航栏透明度变化的轻量级库,通过Runtime运行时和

gitblog_00476的博客 535

runtime实践之Method Swizzling

利用 Objective-C 的 Runtime 特性,我们可以给语言做扩展,帮助解决项目开发中的一些设计和技术问题。这一篇,我们来探索一些利用 Objective-C Runtime 的黑色技巧。这些技巧中最具争议的或许就是 Method Swizzling 。 介绍一个技巧,最好的方式就是提出具体的需求,然后用它跟其他的解决方法做比较。 所以,先来看看我们的需求:对 App 的用户行为进行...

weixin_33979363的博客 117

runtime 第四部分method swizzling

接上一篇http://www.cnblogs.com/ddavidXu/p/5924597.html 转载来源http://www.jianshu.com/p/6b905584f536 http://southpeak.github.io/2014/10/30/objective-c-runtime-2/ runtime的黑魔法,就是可以实现交换两个方法的实现,这就意味着我们可...

dayinyong7118的博客 129

ios runtime浅析(三):Method Swizzling

看到nshipster 的Method Swizzling这篇不错的文章还没翻译,就补充一下,没有逐字翻译,关于associated objects已经有翻译了,大家也可以去了解一下。   method swizzling也许是runtime中最有争议的技术,它的作用就是改变已经存在selector的实现,之所以可以这样是因为方法调用可以在运行时改变:通过改变类的分发表( dispatch tab...

chqj_163的专栏 257

IOS开发-ios runtime-Method Swizzling

method swizzling也许是runtime中最有争议的技术,它的作用就是改变已经存在selector的实现,之所以可以这样是因为方法调用可以在运行时改变:通过改变类的分发表( dispatch table,该表包含selector的名称及对应实现函数的地址)里selector和实现之间的对应关系。  举个例子,比如你想记录一个iOS应用里每个view controller显...

aibi2462的博客 245

iOS 开发:『Runtime』详解(二)Method Swizzling

本文首发于我的个人博客:『不羁阁』 文章链接:传送门 本文更新时间:2019年07月12日13:21:26 本文用来介绍 iOS 开发中『Runtime』中的黑魔法 Method Swizzling。通过本文,您将了解到: Method Swizzling(动态方法交换)简介 Method Swizzling 使用方法(四种方案) Method Swiz...

程序员充电站(itcharge) 919
上一篇: Objective-C 对象模型
下一篇: iOS UIBezierPath类 介绍
直隶码农
博客等级 码龄19年 95粉丝 103原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值