我们都知道iOS中采用引用计数的技术来管理内存,当一个对象没有任何一个地方引用的时候会自动释放,此时的retainCount为0,而且提供了一个-(NSInteger)retainCount的方法来获得对象当前的持有数。

这个概念清楚而明确,不过,让我们看两段代码:

    NSNumber *number = [NSNumber numberWithInt:1];
NSLog(@"retainCount = %lu",[number retainCount]);

这段代码的运行结果是什么?

    NSString *string = [NSString stringWithFormat:@"foo"];
NSLog(@"retainCount = %lu", [string retainCount]);

这一段呢?

在Xcode5.0, ARC关闭的情况下运行,结果是:

2014-01-13 22:08:13.217 blockTest[2732:303] retainCount = 9223372036854775807

2014-01-13 22:08:13.218 blockTest[2732:303] retainCount = 1

这个很出人意料啊,第二段看上去很符合我们的预期,但第一段就有点让人掉眼镜了。

查阅了一下官方的文档,第一句就是“Do not use this method.”,后面给出了说明,因为Autorelease pool的存在,对于内存的管理会相当复杂,retainCount就不能用作调试内存时的依据了。这样对于第一段的结果就可以理解了,可能系统对于这一个特殊的对象有特殊的处理(没准framework里面有早就创建了这个对象了),于是我们拿到了一个非常出人意料的结果。

想想见过的如下的代码就很有点吓人了:

    while ([a retainCount] > 0) {
[a release];
}

如果运行结果正确,那么这是多么幸运的一个人啊!

但对于内存的思考我们可以更进一步,看一段代码:

#import <Foundation/Foundation.h>

@interface Person : NSObject

@property(nonatomic, retain) NSString *name;
@property(nonatomic, assign) NSInteger age; @end @implementation Person
- (id)init
{
self = [super init];
if (self) {
self.name = @"name";
self.age = 20;
}
return self;
} - (void)dealloc
{
NSLog(@"dealloc");
[super dealloc];
} @end int main(int argc, const char * argv[])
{
Person *per1 = [[Person alloc] init];
//NSLog(@"retainCount = %lu -- 0",[per1 retainCount]);
[per1 release];
per1.age = 22;
NSLog(@"retainCount = %lu -- 1, age = %ld",[per1 retainCount], per1.age);
//[per1 retain];
//per1.age = 23;
//NSLog(@"retainCount = %lu -- 2, age = %ld",[per1 retainCount], per1.age); return 0;
}

这段代码的运行结果居然是:

2014-01-13 22:17:11.619 blockTest[2758:303] dealloc

2014-01-13 22:17:11.621 blockTest[2758:303] retainCount = 1 -- 1, age = 22

这个问题位于http://www.cocoachina.com/ask/questions/show/106777#36483,个人猜测是对象确实销毁了,毕竟dealloc都调用了,但内存里面数据仍然存在,立刻打印是存在内容的,至于retainCount不是0,只能说明对象即使已经销毁了,这个值仍然可能大于0。

iOS中的retainCount的更多相关文章

  1. iOS中assign、copy 、retain等关键字的含义

    iOS中assign.copy .retain等关键字的含义  转自:http://my.oschina.net/majiage/blog/267409 assign: 简单赋值,不更改索引计数cop ...

  2. iOS中引用计数内存管理机制分析

    在 iOS 中引用计数是内存的管理方式,虽然在 iOS5 版本中,已经支持了自动引用计数管理模式,但理解它的运行方式有助于我们了解程序的运行原理,有助于 debug 程序. 操作系统的内存管理分成堆和 ...

  3. iOS 中Block以及Blocks的使用,闭包方法调用

    OC: -(void)dataWithUrl:(NSString*)string AndId:(NSInteger)id returnName:(void(^)(NSString*name))back ...

  4. 【iOS系列】-iOS中内存管理

    iOS中创建对象的步骤: 1,分配内存空间,存储对象 2,初始化成员变量 3,返回对象的指针地址 第一:非ARC机制: 1,对象在创建完成的同时,内部会自动创建一个引用计数器,是系统用来判断是否回收对 ...

  5. iOS中代理属性为什么要用Weak修饰?

    一.写在前面 代理设计模式,在iOS开发过程中,是一个非常常见的设计模式,可以说用的范围非常广泛,而对初学者来讲,常常对代理的属性修饰用weak存在疑惑,因此下面就解释一下其中非常简单的道理. 二.必 ...

  6. iOS中支付宝集成

    iOS中支付宝集成 如今各种的App中都使用了三方支付的功能,现在将我在使用支付宝支付集成过程的心得分享一下,希望对大家都能有所帮助 要集成一个支付宝支付过程的环境,大致需要: 1>公司:先与支 ...

  7. iOS中数据库应用基础

    iOS 数据库入门 一.数据库简介 1.什么是数据库? 数据库(Database) 是按照数据结构来组织,存储和管理数据的仓库 数据库可以分为2大种类 关系型数据库(主流) PC端 Oracle My ...

  8. 正则表达式在iOS中的运用

    1.什么是正则表达式 正则表达式,又称正规表示法,是对字符串操作的一种逻辑公式.正则表达式可以检测给定的字符串是否符合我们定义的逻辑,也可以从字符串中获取我们想要的特定部分.它可以迅速地用极简单的方式 ...

  9. iOS 中的 HotFix 方案总结详解

    相信HotFix大家应该都很熟悉了,今天主要对于最近调研的一些方案做一些总结.iOS中的HotFix方案大致可以分为四种: WaxPatch(Alibaba) Dynamic Framework(Ap ...

随机推荐

  1. PHP中的数组方法及访问方法总结

    一.数组操作的基本函数 数组的键名和值 array_values($arr);获得数组的值 array_keys($arr);获得数组的键名 array_flip($arr);数组中的值与键名互换(如 ...

  2. 论山寨手机与Android联姻 【3】手机是怎样生产出来的

    要说清楚MTK在商业模式上有什么优势,以及Android对于MTK未来的手机开发会有什么影响,首先得了解手机从设计,开发到生产的整个过程.让我们先来看看手机的生产过程.在生产制造环节,山寨手机和正牌手 ...

  3. C++ 文件的复制、删除、重命名

    一.文件的复制 #include <iostream>#include <fstream>using namespace std; int CopyFile(char *Sou ...

  4. NPOI操作EXCEL--设置密码及设置只读

    有时,我们可能需要某些单元格只读,如在做模板时,模板中的数据是不能随意让别人改的.在Excel中,可以通过“审阅->保护工作表”来完成,如下图:      那么,在NPOI中有没有办法通过编码的 ...

  5. OpenStreetMap(OSM) for developers

    This article from: http://wiki.openstreetmap.org/wiki/Develop OpenStreetMap isn't just open data - i ...

  6. C#中dynamic的正确用法【转】

    dynamic是FrameWork4.0的新特性.dynamic的出现让C#具有了弱语言类型的特性.编译器在编译的时候不再对类型进行检查,编译期默认dynamic对象支持你想要的任何特性.比如,即使你 ...

  7. Unity大中华区主办 第二届Unity 游戏及应用大赛 实力派精品手游盘点

    Unity是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏.建筑可视化.实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎.包含如今时 ...

  8. 说说数据库架构,ORM缓存和路由

    为什么在ORM层做缓存,而不是DB层 ORM能有效地提高程序员的开发效率,程序员更喜欢操作对象而不是数据库,他们不关心也不想手写一堆SQL语句,毕竟一个公司里普通程序员要占多数,他们并不是非常熟悉数据 ...

  9. 使用logstash收集日志的可靠性验证

    实时计算里,需要对日志实时收集,logstash可以做到.目前的版本是1.4.2,官方文档在http://www.logstash.net/docs/1.4.2/,里面有详细的配置说明,使用也很简单. ...

  10. JS 精粹( 函数)

    函数是对象,它与其它对象唯一的不同是它可以调用.函数可实现:代码复用.信息隐藏.代码组合调用. 建立函数时会建立:上下文.调用函数的代码.每个函数(除Function.prototype)都会有一个原 ...