iOS 注入三种方式详解
在 iOS 开发中,经常会遇到需要注入代码或者资源的情况。常见的注入方式有三种:运行时注入、类目注入和动态库注入。在这篇文章中,我们将通过一个小白的角度,逐步了解这三种注入方式的基本流程、实例代码及注意事项。
注入流程概览
下面是注入的基本流程及每种方法的步骤:
步骤 | 运行时注入 | 类目注入 | 动态库注入 |
---|---|---|---|
1 | 获取目标类 | 创建类目文件 | 创建动态库项目 |
2 | 编写注入函数 | 在类目中实现方法 | 实现注入的功能 |
3 | 调用注入函数 | 使用该类目 | 加载动态库 |
4 | 测试验证 | 测试验证 | 测试验证 |
注入方式详解
1. 运行时注入
步骤详解:
- 获取目标类。
- 编写注入函数。
- 调用注入函数。
- 测试验证。
示例代码:
#import <objc/runtime.h>
// 目标类的方法
@interface MyTargetClass : NSObject
- (void)originalMethod;
@end
@implementation MyTargetClass
- (void)originalMethod {
NSLog(@"Original Method");
}
@end
// 注入的方法
void myInjectedMethod(id self, SEL _cmd) {
NSLog(@"Injected Method Called");
// 调用原方法
((void (*)(id, SEL))objc_msgSend)(self, @selector(originalMethod));
}
// 注入函数
void injectMethod() {
Class targetClass = [MyTargetClass class];
SEL originalSelector = @selector(originalMethod);
SEL swizzledSelector = @selector(myInjectedMethod);
Method originalMethod = class_getInstanceMethod(targetClass, originalSelector);
Method swizzledMethod = class_getInstanceMethod(targetClass, swizzledSelector);
method_exchangeImplementations(originalMethod, swizzledMethod);
}
// 在合适的地方调用注入函数
// injectMethod();
2. 类目注入
步骤详解:
- 创建类目文件。
- 在类目中实现方法。
- 使用该类目。
- 测试验证。
示例代码:
// MyTargetClass+Swizzle.h
#import "MyTargetClass.h"
@interface MyTargetClass (Swizzle)
- (void)swizzledMethod;
@end
// MyTargetClass+Swizzle.m
#import "MyTargetClass+Swizzle.h"
@implementation MyTargetClass (Swizzle)
- (void)swizzledMethod {
NSLog(@"Swizzled Method Called");
// 调用原方法
[self swizzledMethod]; // 注意:会调用到自己
}
// 在使用到MyTargetClass的地方
// [MyTargetClass new].swizzledMethod();
3. 动态库注入
步骤详解:
- 创建动态库项目。
- 实现注入的功能。
- 加载动态库。
- 测试验证。
示例代码:
// DynamicLibrary.m
#import <Foundation/Foundation.h>
__attribute__((constructor))
void dynamicLibraryEntryPoint() {
NSLog(@"Dynamic library loaded");
// 做一些注入操作
}
// 加载动态库
// dlopen("/path/to/DynamicLibrary.dylib", RTLD_NOW);
类图说明
以下是我们讨论的三个注入方式的类图示意:
classDiagram
class MyTargetClass {
+void originalMethod()
}
class MyDynamicLibrary {
+void dynamicLibraryEntryPoint()
}
class MyCategory {
+void swizzledMethod()
}
MyTargetClass --> MyCategory : Injects
MyTargetClass --> MyDynamicLibrary : Depends on
结论
通过以上步骤,我们简单了解了 iOS 三种注入方式的实现过程。每种方式都有其独特的优缺点和适用场景。在实际开发中,选择合适的注入方法对于构建高效、稳定的应用至关重要。希望以上内容能够帮助刚入行的小白开发者快速掌握 iOS 注入的相关知识与技巧。