/images/avatar.png

NSProxy AOP

iOS AOP文章系列 前导知识: Mach-O文件结构分析 静态链接&动态链接 OC方法&OC类&OC对象 方法查找和消息转发 AOP框架: Method Swizzling Fishhook Apsects NSProxy AOP 介绍 iOS 有一个原生的 AOP 方法,就是利用 NSProxy 代理类!,我们先看下官网介绍: Quote Typically, a message to a proxy is forwarded to the real object or causes the proxy to load (or transform itself into) the real object. Subclasses of NSProxy can be used to implement transparent distributed messaging (for example, NSDistantObject) or for lazy instantiation of objects that are expensive to create.

Apsects

iOS AOP文章系列 前导知识: Mach-O文件结构分析 静态链接&动态链接 OC方法&OC类&OC对象 方法查找和消息转发 AOP框架: Method Swizzling Fishhook Apsects NSProxy AOP 介绍 Quote Think of Aspects as method swizzling on steroids. It allows you to add code to existing methods per class or per instance, whilst thinking of the insertion point e.g. before/instead/after. Aspects automatically deals with calling super and is easier to use than regular method swizzling. 从 Apsects 的介绍可以看到利用 swizzling 技术来达到为类方法或实例方法添加额外逻辑。且有 before / instead / after 三种场景。

Fishhook

iOS AOP文章系列 前导知识: Mach-O文件结构分析 静态链接&动态链接 OC方法&OC类&OC对象 方法查找和消息转发 AOP框架: Method Swizzling Fishhook Apsects NSProxy AOP fishhook 是 facebook 开源的一款简单易用的动态 hook 框架。一起学习下其原理。 还是那个🌰 在 OC方法&OC类&OC对象 中讲元类的时候分配注册了一个 Student 类,并实现了 study 方法,but 学生表面学习,内心还是向往诗和远方,因此我们想通过 Fishhook 动态 Hook NSLog 系统函数来表达学生党的真实内心: // main.m void StudyFunction(id self, SEL _cmd) { NSLog(@"i am studing"); } // 定义函数指针用来保存原始函数 static void (*orig_nslog)(NSString * format,...); // 定义新函数扩展 NSLog void newNSLog(NSString * format,...) { format = [format stringByAppendingFormat:@"\tOS: i want to play!

Method Swizzling

iOS AOP文章系列 前导知识: Mach-O文件结构分析 静态链接&动态链接 OC方法&OC类&OC对象 方法查找和消息转发 AOP框架: Method Swizzling Fishhook Apsects NSProxy AOP iOS AOP 接下来的文章我们正式进入 iOS AOP 的世界。 AOP 是一种面向切面编程,核心思想是在不修改源码情况下给程序添加功能的技术。 根据 OC 的 runtime 特性,我们先来介绍比较基础的一种实现方式 – Method Swizzling。 🌰 演示 我们依旧使用 前导知识文章 中的 Demo,先为 Person 添加一个 Category 类来扩展一个 eat 方法,毕竟干饭人除了睡还要吃,要不和咸鱼有什么区别,我们想在 人 睡前先 吃饱饭,该如何利用 Swizzling 实现呢? // Person.m @implementation Person - (void)sleep { NSLog(@"i am sleeping"); } @end // Person+swizzle.m @implementation Person (swizzle) - (void)eat { NSLog(@"i am eating"); // 这里调用自身并不会导致递归调用 // 因为在 main 中交换了 eat 和 sleep 的 IMP,所以这里实际上调用的是 sleep [self eat]; } @end // main.

方法查找和消息转发

iOS AOP文章系列 前导知识: Mach-O文件结构分析 静态链接&动态链接 OC方法&OC类&OC对象 方法查找和消息转发 AOP框架: Method Swizzling Fishhook Apsects NSProxy AOP Tip 源码分析环境:objc4-818.2 根据之前的文章我们知道OC方法的本质就是调用 obj_msgSend,那么我们具体分析下 ObjC 下方法的查找和转发机制。 obj_msgSend 的实现在 obj-msg-rm64.s 中的汇编代码为: ENTRY _objc_msgSend UNWIND _objc_msgSend, NoFrame cmp p0, #0 // nil check and tagged pointer check #if SUPPORT_TAGGED_POINTERS b.le LNilOrTagged // (MSB tagged pointer looks negative) #else b.eq LReturnZero #endif ldr p13, [x0] // p13 = isa GetClassFromIsa_p16 p13, 1, x0 // p16 = class LGetIsaDone: // calls imp or objc_msgSend_uncached CacheLookup NORMAL, _objc_msgSend, __objc_msgSend_uncached #if SUPPORT_TAGGED_POINTERS LNilOrTagged: b.

OC方法&OC类&OC对象

iOS AOP文章系列 前导知识: Mach-O文件结构分析 静态链接&动态链接 OC方法&OC类&OC对象 方法查找和消息转发 AOP框架: Method Swizzling Fishhook Apsects NSProxy AOP Tip 源码分析环境:objc4-818.2 OC方法 通过之前的文章 Mach-O文件结构分析 我们得知OC方法在编译时调用了 objc_msgSend 函数 int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... NSLog(@"Hello, World!"); Person *p = [[Person alloc] init]; [p walk]; [p ill]; [p sleep]; run(); } return 0; } clang -rewrite-objc main.m -o main.cpp