iOS中的retainCount
我们都知道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的更多相关文章
- iOS中assign、copy 、retain等关键字的含义
iOS中assign.copy .retain等关键字的含义 转自:http://my.oschina.net/majiage/blog/267409 assign: 简单赋值,不更改索引计数cop ...
- iOS中引用计数内存管理机制分析
在 iOS 中引用计数是内存的管理方式,虽然在 iOS5 版本中,已经支持了自动引用计数管理模式,但理解它的运行方式有助于我们了解程序的运行原理,有助于 debug 程序. 操作系统的内存管理分成堆和 ...
- iOS 中Block以及Blocks的使用,闭包方法调用
OC: -(void)dataWithUrl:(NSString*)string AndId:(NSInteger)id returnName:(void(^)(NSString*name))back ...
- 【iOS系列】-iOS中内存管理
iOS中创建对象的步骤: 1,分配内存空间,存储对象 2,初始化成员变量 3,返回对象的指针地址 第一:非ARC机制: 1,对象在创建完成的同时,内部会自动创建一个引用计数器,是系统用来判断是否回收对 ...
- iOS中代理属性为什么要用Weak修饰?
一.写在前面 代理设计模式,在iOS开发过程中,是一个非常常见的设计模式,可以说用的范围非常广泛,而对初学者来讲,常常对代理的属性修饰用weak存在疑惑,因此下面就解释一下其中非常简单的道理. 二.必 ...
- iOS中支付宝集成
iOS中支付宝集成 如今各种的App中都使用了三方支付的功能,现在将我在使用支付宝支付集成过程的心得分享一下,希望对大家都能有所帮助 要集成一个支付宝支付过程的环境,大致需要: 1>公司:先与支 ...
- iOS中数据库应用基础
iOS 数据库入门 一.数据库简介 1.什么是数据库? 数据库(Database) 是按照数据结构来组织,存储和管理数据的仓库 数据库可以分为2大种类 关系型数据库(主流) PC端 Oracle My ...
- 正则表达式在iOS中的运用
1.什么是正则表达式 正则表达式,又称正规表示法,是对字符串操作的一种逻辑公式.正则表达式可以检测给定的字符串是否符合我们定义的逻辑,也可以从字符串中获取我们想要的特定部分.它可以迅速地用极简单的方式 ...
- iOS 中的 HotFix 方案总结详解
相信HotFix大家应该都很熟悉了,今天主要对于最近调研的一些方案做一些总结.iOS中的HotFix方案大致可以分为四种: WaxPatch(Alibaba) Dynamic Framework(Ap ...
随机推荐
- Android Permissions管理之用户拒绝授权
Android Permissions管理之用户拒绝授权,在Marshmallow之前的安卓版本,应用的权限只需要注册一下,应用就会获取到,在Marshmallow之后,为了安全,全新的权限模型出现, ...
- ie兼容---haslayout
要想更好的理解 css, 尤其是 IE 下对 css 的渲染,haslayout 是一个非常有必要彻底弄清除的概念.大多IE下的显示错误,就是源于 haslayout. 什么是 haslayout ? ...
- 前端开发面试题收集 css
什么是CSS盒子模型 页面上的每个元素都被浏览器看做是一个矩形的盒子. 由内容.填充.边框.边界组成. 什么是 css sprite 将多个图片拼接在一个图片中,通过background-positi ...
- 分支-03. 三天打鱼两天晒网-B3
/*B3-分支-03. 三天打鱼两天晒网 *Main.c *测试通过 */ #include <stdio.h> #include <stdlib.h> int main() ...
- Amazon MWS 上传数据 (三) 提交请求
前面介绍了设置服务和构造请求,现在介绍提交请求. 上传数据,查询上传操作的工作状态,和处理上传操作返回的报告操作使用的Amazon API 分别为:SubmitFeed(),FeedSubmissio ...
- Keli Linux与网络安全(2)——初探Keli
Kali是BackTrack的升级换代产品,按照官方网站的定义,Kali Linux是一个高级渗透测试和安全审计Linux发行版.作为使用者,我简单的把它理解为,一个特殊的Linux发行版,集成了精心 ...
- PS快捷键大全
一.工具箱(多种工具共用一个快捷键的可同时按[Shift]加此快捷键选取) 矩形.椭圆选框工具 [M] 移动工具 [V] 套索.多边形套索.磁性套索 [L] 魔棒工具 [W] 裁剪工具 [C ...
- Effective C++笔记 55条编程法则
1. 视C++为一个语言联邦 C++高效编程守则视状况而变化,取决于你使用C++的哪一部分. 2. 尽量以const,enum.inline替代#define 1) 对于单纯常量,最好以const ...
- UITabBarController 笔记(一)AppDelegate中加UITabBarController 为 rootViewController
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launc ...
- jQuery源码笔记——四
each()实现 var jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context ) ...