DDZombieMonitor

核心代码分析:

自定义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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 面向对象的三大特性:封装、继承、多态 OC内存管理 _strong 引用计数器来控制对象的生命周期。 _weak...
    运气不够技术凑阅读 4,849评论 0 10
  • 成因 野指针就是指向一个已删除的对象或者受限内存区域的指针。我们写C++的时候强调指针初始化为NULL,强调用完后...
    上官soyo阅读 21,205评论 4 80
  • 一、自定义kvo 在上篇文章 kvo原理分析[https://www.jianshu.com/u/a569f590...
    HotPotCat阅读 3,798评论 1 2
  • 网络问题 HTTP get 和 post 的区别 get通过URL向Server获取数据,也可以在URL里向Ser...
    quantiza阅读 3,813评论 0 3
  • ios的风已吹过,继续ios还是走c/c++后台开发?或者风停了猪都摔下来了,需要更专业的人士?你为什么拿高薪?别...
    桃逸阅读 3,604评论 0 0

友情链接更多精彩内容