核心代码分析:
自定义Dealloc:
- (void)newDealloc:(__unsafe_unretained id)obj {
if ([self shouldDetect:[obj class]]) {
void *p = (__bridge void *)obj;
size_t memSize = malloc_size(p);
if (memSize >= [DDZombie zombieInstanceSize]) {//有足够的空间才覆盖
Class origClass = object_getClass(obj);
///析构对象
objc_destructInstance(obj);
///填充0x55能稍微提升一些crash率
memset(p, 0x55, memSize);
memset(p, 0x00, [DDZombie zombieInstanceSize]);
///把我们自己的类的isa复制过去
Class c = [DDZombie zombieIsa];
memcpy(obj, &c, sizeof(void*));
DDZombie* zombie = (DDZombie*)p;
zombie.realClass = origClass;
//默认为true,即:默认会记录当前僵尸对象释放时的调用栈
if (_traceDeallocStack) {
DDThreadStack *stack = hy_getCurrentStack();
zombie.threadStack = stack;
memSize += stack->occupyMemorySize();
}
//check是否达到内存阈值,达到阈值需要释放一部分内存
[self freeMemoryIfNeed];
//更新内存占用值:_occupyMemorySize
__sync_fetch_and_add(&_occupyMemorySize, (int)memSize);
//如果保存僵尸对象的队列满了,先将队头的僵尸对象移除并释放内存,再将当前僵尸对象入队。
void *item = ds_queue_put_pop_first_item_if_need(_delayFreeQueue, p);
if (item) {
[self freeZombieObject:item];
}
} else {
[obj performSelector:@selector(hy_originalDealloc)];
}
} else {
[obj performSelector:@selector(hy_originalDealloc)];
}
}
流程总结 & 验证:
1、析构对象
2、给指针内容填充上0x55
3、把DDZombie的isa复制到obj指针中
4、将obj原来的类型赋值给僵尸对象的realClass字段