核心代碼分析:
自定義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

image
3、把DDZombie的isa復制到obj指針中

image
4、將obj原來的類型賦值給僵尸對象的realClass字段

image