iOS中僵尸对象的实现方法

什么是僵尸对象?所谓僵尸,就是过度释放的对象。在ios开发中,僵尸对象对于开发人员调试程序来说很有用。我们通常将NSZombieEnabled环境变量设置为YES来打开僵尸对象,但这会导致所有的对象都不会被释放,程序长时间运行会占用大量内存。
那有么有什么其他方法来实现僵尸对象呢?下面小编就给大家介绍下,模仿XCode用代码实现僵尸对象的方法。
创建僵尸对象
在ios开发中,当一个普通对象的retainCount变成0的时候,会调用dealloc,代码要勾住dealloc后,就可进行一下操作:
1、创建一个新的僵尸类;
2、将此对象的isa指向僵尸类(这个对象就变成了僵尸类的对象了)
这样,以后所有发向这个对象的消息现在都会去僵尸类中找实现的方法,因为僵尸类没有自己的方法,所以会forwardInvocate:(NSInvocation*),在这之前,系统还会根据消息的selector,调用methodSignatureForSelector:方法生成NSInvocation对象,所以第一时间发现给僵尸对象的消息的时机是在methodSignatureForSelector:中。
僵尸类的实现需要满足的细节
1、不可以像实现普通类一样继承自NSObject,否则我们继承了很多NSObject中的方法,就不能够在methodSignatureForSelector:中截获这个消息;
2、需要实现methodSignatureForSelector:方法,在这里打印出相关的信息;
3、需要实现+initialize方法,这个方法是所有类被发送第一个方法前会调用的一个方法,如果僵尸类没有实现这个方法,那么就会forwardInvocate:了。
获取原始类名的方法
虽然我们可以在methodSignatureForSelector:中截获这个消息,但是这个对象的isa指针已经指向了僵尸类,怎样得到原始类的名字呢?有一个巧妙的办法就是创建的这个新的僵尸类的名字要用一下规则命名:NSZombie+原始类的名字,在methodSignatureForSelector:中就可以将前缀NSZombie去掉,得到原始类名了。
僵尸类的实现
@implementation NSZombie
- (id)init
{
self = [super init] ;
if (self) {
NSIndexSet *obj = [[NSIndexSet alloc] init];
[NSZombie dump:obj] ;
[obj release];
[NSZombie dump:obj] ;
}
return self ;
}
+ (void)dump:(id)obj
{
size_t size = malloc_size(obj) ;
NSLog(@"size:%zu, className:%s", size, object_getClassName(obj)) ;
}
@end
没有开启NSZombieEnabled的情况下,虽然对象已经被释放,但是这块内存并没有被复写,所以还是能够通过isa指针找对应类的信息的。size:16, className:NSIndexSetsize:0, className:NSIndexSet
开启了NSZombieEnabled之后,得到了,可以看到对象引用计数变成0之后,对象对应的类已经被改变,变成了一个僵尸对象。size:16, className:NSIndexSetsize:16, className:_NSZombie_NSIndexSet
以上就是僵尸类的创建、实现、用法相关知识,学习并掌握这些知识,对ios开发人员来说非常重要,不知不会创建僵尸对象的你学会了么?当然也欢迎分享更easy实现僵尸对象的方法。
iOS中僵尸对象的实现方法的更多相关文章
- IOS中图片拉伸技巧与方法总结(转载)
以下内容转载自:http://my.oschina.net/u/2340880/blog/403996 IOS中图片拉伸技巧与方法总结 一.了解几个图像拉伸的函数和方法 1.直接拉伸法 简单暴力,却是 ...
- iOS 关于僵尸对象和僵尸指针的那些事儿
引言 提到僵尸就感到一种恐怖,大家都知道“僵尸”是没有生命的,但是它确实是一种存在的类似生命体的一种生物.哈哈,当然本文的重点不是讨论“僵尸”,而是有关于ios当中经常遇到的僵尸指针(Zombie P ...
- js中Number对象与MATH方法整理总结
W3C的文档: Number 对象属性 属性 描述 constructor 返回对创建此对象的 Number 函数的引用. MAX_VALUE 可表示的最大的数. MIN_VALUE 可表示的最小的数 ...
- iOS——浅谈iOS中三种生成随机数方法
ios 有如下三种随机数方法:
- iOS中归档对象的创建,数据写入与读取
归档(archiving)是指另一种形式的序列化,但它是任何对象都可以实现的更常规的模型.专门编写用于保存数据的任何模型对象都应该支持归档.比属性列表多了很良好的伸缩性,因为无论添加多少对象,将这些对 ...
- python中datetime模块中datetime对象的使用方法
本文只讲述datetime模块中datetime对象的一些常用的方法,如果读者需要更多datetime模块的信息,请查阅此文档. datetime模块的对象有如下: timedelta date da ...
- iOS中UIPickerView常见属性和方法的总结
UIPickerView是iOS中的原生选择器控件,使用方便,用法简单,效果漂亮. @property(nonatomic,assign) id<UIPickerViewDataSource&g ...
- iOS中的几个重要方法
iOS开发中几个重要的方法: 加载类到内存,程序刚启动的时候调用,调用在main函数之前 1.+(void)load{ } 初始化类,类第一次使用的时候调用一次 2.+(void)initialize ...
- javascript中字符串对象常用的方法和属性
前言 字符串是一种非常重要的数据类型,在Java等面向对象编程语言中,它代表对象类型,而在javascript中它却是一种基本数据类型,在开发的领域中,我们经常会碰到,无论是前端还是后台.比如后台验证 ...
随机推荐
- 【在线】Actionbar Style Generator:ActionBar风格生成器
这个ActionBar风格生成器可以让你轻松地创建一个简洁.有吸引力且无漏洞的自定义actionbar.它会生成所有9种必须的patch assets以及相关XML的drawables和styles文 ...
- lucene-源码分析
lucene-源码分析 http://www.cnblogs.com/forfuture1978/p/3940965.html
- java的io读取
package gys; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; imp ...
- easyui tabs内容panel自适应窗体宽度方法
废话不说,直接上代码: $('#Teacherwin_details').window({ title: '查看教职工信息', width: 800, height: 520, top: ($(win ...
- android studio 更新 Gradle错误解决方法
Android Studio每次更新版本都会更新Gradle这个插件,但由于长城的问题每次更新都是失败,又是停止在Refreshing Gradle Project ,有时新建项目的时候报 Gradl ...
- 异步任务神器 Celery 简明笔记
转自:http://www.jianshu.com/p/1840035cb510 异步任务 异步任务是web开发中一个很常见的方法.对于一些耗时耗资源的操作,往往从主应用中隔离,通过异步的方式执行.简 ...
- [HDU 5135] Little Zu Chongzhi's Triangles (dfs暴搜)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5135 题目大意:给你n条边,选出若干条边,组成若干个三角形,使得面积和最大.输出最大的面积和. 先将边 ...
- 通过反射获取父类中的泛型参数对应的Class对象
假设有两个类:Dao 和 PersonDao,它们的代码如下: Dao: public class Dao<T> { private Class<T> clazz; T get ...
- 利用UDP19端口实施DOS攻击的真实案例
昨天在一个用户现场发现了一个利用UDP19端口对互联网受害者主机进行DOS攻击的真实案例.这个情况是我第一次见到,个人认为对以后遇到此类情况的兄弟具有参考价值.有必要做一个简单的分析记录. 在此次的分 ...
- 使用Zabbix监控RabbitMQ
一 应用场景描述 线上业务使用RabbitMQ作为消息队列中间件,那么作为运维人员对RabbitMQ的监控就很重要,本文就针对如何从头到尾使用Zabbix来监控RabbitMQ进行说明. 二 Rabb ...