一丶使用场景
修改第三方库的代码,hook太复杂,直接写个B类;重定向,修改源码;
完美
二丶具体实施
A类
@interface ZBAAAA : NSObject
@end
@implementation ZBAAAA
@end
B类
@interface ZBBBBB : NSObject
- (void)bbbb;
@end
@implementation ZBBBBB
//必须实现
- (instancetype)alloc
{
return [[self class] alloc];
}
- (void)bbbb
{
NSLog(@"%s",__func__);
}
@end
结果:

三丶解释
知识点:
isa机制图

- (NSArray *)NSObjectMetaMethodList {
u_int count;
NSMutableArray *methodList = [NSMutableArray array];
Class metaClass = objc_getMetaClass([@"NSObject" UTF8String]);
Method *methods = class_copyMethodList(metaClass, &count);
for (int i = 0; i < count; i++) {
SEL name = method_getName(methods[i]);
NSString *strName = [NSString stringWithCString:sel_getName(name)
encoding:NSUTF8StringEncoding];
[methodList addObject:strName];
}
free(methods);
return methodList;
}
- (NSArray *)methodList {
u_int count;
NSMutableArray *methodList = [NSMutableArray array];
Method *methods = class_copyMethodList([self class], &count);
for (int i = 0; i < count; i++) {
SEL name = method_getName(methods[i]);
NSString *strName = [NSString stringWithCString:sel_getName(name)
encoding:NSUTF8StringEncoding];
[methodList addObject:strName];
}
free(methods);
return methodList;
}
首先,alloc方法是在NSObject的meta类里;
[ZBAAAA alloc]

通过object_setClass
[ZBAAAA alloc]变成

本来Aclass 的isa 会到 AMeta里面去找,最终到root meta class 里面找到alloc;
重定向B之后
Aclass 的isa 会到 Bclass里面去找,最终到B root class (NSObject);NSObject里面压根没有alloc;
所以需要
@implementation ZBBBBB
//必须实现
- (instancetype)alloc
{
return [[self class] alloc];
}
- (void)bbbb
{
NSLog(@"%s",__func__);
}
@end
网友评论