文章目录
  1. 1. dealloc

dealloc

我们经常会在开发过程中遇到这样的问题:检测某个 ViewController 是否在 pop 后被释放。通常情况下,我们可以通过将项目中所有的 ViewController 继承自某个自定义的类,然后在该类中重写 dealloc 方法。另一种是更笨的办法:手动在我们需要检测的类中手动重写 dealloc 方法。

其实这两种方法都各有优劣,具体我就不想再分析了。实际上,除了上述两种办法,还有一种更好的办法来解决这样一个需求,就是我们标题所说到 Objective-C 中的 Runtime

Runtime 顾名思义就是运行时,由于 Objective-C 是一门动态语言,很多事情都不是放在编译而是运行时做的。具体的理论我就不再赘述,总之在这个需求中,Runtime 的特性能很好的满足我们的需求。

首先 创建一个 UIViewControllerCategory,在 Category 中重写 load方法,详细代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
+ (void)load {
[super load];

// 由于 ARC 中不允许手动调用 dealloc 方法,所以 originSEL 使用 NSSelectorFromString()来获取
SEL originSEL = NSSelectorFromString(@"dealloc");
SEL swapSEL = @selector(zecDealloc);

Method originMethod = class_getInstanceMethod(self, originSEL);
Method swapMethod = class_getInstanceMethod(self, swapSEL);

IMP originIMP = method_getImplementation(originMethod);
IMP swapIMP = method_getImplementation(swapMethod);

BOOL didAddMethod = class_addMethod(self, originSEL, swapIMP, method_getTypeEncoding(originMethod));

if(didAddMethod) {
class_replaceMethod(self, swapSEL, originIMP, method_getTypeEncoding(originMethod));
} else {
method_exchangeImplementations(originMethod, swapMethod);
}
}

- (void)zecDealloc {
NSLog(@"Dealloc ---- %@",[self class]);
}

这段代码的功能就是将系统的 dealloc 方法用重写的 zecDealloc 方法替代,而实现替换的主要功臣是 class_replaceMethod()method_exchangeImplementations() 两个 Runtime 方法,根据方法名,这两个方法的具体作用也很好理解。

RuntimeObjective-C 的一把双刃剑,我自己也会在以后的实际项目中慢慢学习和总结。

文章目录
  1. 1. dealloc