背景:有一个第三方framework中,其api生成一个封装好的页面的viewcontroller对象,需要监控改vc的释放时机以便做一些逻辑处理。但由于是第三方内部封装,无法继承重写子类dealloc,且示例对象是第三方内部创建好之后返回给外部,只能采用一些非常规方法。
思路:当一个对象A强持有另一个对象B时,若B不被其他对象持有,那么当A释放时,B会自动释放。
根据此思路,很容易想到使用runtime给viewController添加一个属性,挂一个用于检测生命周期的实例对象,当vc释放时,检测对象也会释放,触发检测对象的dealloc。虽然此dealloc不一定在vc释放时立即触发,但基本上是满足需求的。
CLDeallocParasite.h
@interface CLDeallocParasite : NSObject
@property (nonatomic, copy) void(^clDeallocBlock)(void);
@end
CLDeallocParasite.m
#import "CLDeallocParasite.h"
@implementation CLDeallocParasite
- (void)dealloc {
if (self.clDeallocBlock) {
self.clDeallocBlock();
}
// NSLog(@"%s",__func__);
}
UIViewController+CLSwizzle.h
@interface UIViewController (CLSwizzle)
- (CLDeallocParasite *)cl_addDeallocBlockParasite;
@end
UIViewController+CLSwizzle.m
#import <objc/message.h>
#import <objc/runtime.h>
@implementation UIViewController (CLSwizzle)
/**
dealloc
*/
- (CLDeallocParasite *)cl_addDeallocBlockParasite {
@synchronized (self) {
static NSString *clDeallockAssociatedKey = @"clDeallockAssociatedKey";
NSMutableArray *parasiteList = objc_getAssociatedObject(self, &clDeallockAssociatedKey);
if (!parasiteList) {
parasiteList = [NSMutableArray new];
objc_setAssociatedObject(self, &clDeallockAssociatedKey, parasiteList, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
CLDeallocParasite * parasite = [CLDeallocParasite new];
[parasiteList addObject:parasite];
return parasite;
}
}
@end
使用:
UIViewController * vc = xxx;
CLDeallocParasite * deallocParasite = [vc cl_addDeallocBlockParasite];
deallocParasite.clDeallocBlock = ^{
//dealloc
};
网友评论