在iOS的開(kāi)發(fā)當(dāng)中、我們需要對(duì)原有的方法進(jìn)行改進(jìn)時(shí),我們可以通過(guò)重寫(xiě)父類實(shí)現(xiàn)。但是,當(dāng)我們需要在所有的子類都要修改父類方法,如果父類是我們自定義的API當(dāng)然可以直接修改API,通常需要修改系統(tǒng)API活著三方庫(kù),就需要用到runtime時(shí)機(jī)制進(jìn)行方法替換活著補(bǔ)救。
本文章以hook原系統(tǒng)的dealloc方法添加一句NSLog來(lái)打印當(dāng)前頁(yè)面的釋放狀態(tài)
采用category重寫(xiě) load 方法,導(dǎo)入工程即可實(shí)現(xiàn)方法的替換
UIViewController+Swizzled.h
//
// UIViewController+Swizzled.h
// FtxBookViaPhone
//
// Created by Jone on 2017/2/13.
// Copyright ? 2017年 FTXJOY. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIViewController (Swizzled)
@end
UIViewController+Swizzled.m
//
// UIViewController+Swizzled.m
// FtxBookViaPhone
//
// Created by Jone on 2017/2/13.
// Copyright ? 2017年 FTXJOY. All rights reserved.
//
#import "UIViewController+Swizzled.h"
@implementation UIViewController (Swizzled)
+(void)load {
[super load];
__weak typeof(self) weakSelf = self;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [weakSelf class];
Method oldMethod = class_getInstanceMethod(weakSelf, NSSelectorFromString(@"dealloc"));
Method newMethod = class_getInstanceMethod(weakSelf, @selector(swizzledDealloc));
BOOL didAddMethod = class_addMethod(class, NSSelectorFromString(@"dealloc"), method_getImplementation(newMethod), method_getTypeEncoding(newMethod));
if (didAddMethod) {
class_replaceMethod(class, @selector(swizzledDealloc), method_getImplementation(oldMethod), method_getTypeEncoding(oldMethod));
} else {
method_exchangeImplementations(oldMethod, newMethod);
}
});
}
- (void)swizzledDealloc {
NSLog(@"print:dealloc-%@",NSStringFromClass([self class]));
[self swizzledDealloc];
}
@end