NSString与奇怪的retainCount
话题从sunnyxx的《黑幕背后的Autorelease》开始
文章开头有个小例子
__weak id reference = nil;
- (void)viewDidLoad {
[super viewDidLoad];
NSString *str = [NSString stringWithFormat:@"sunnyxx"];
// str是一个autorelease对象,设置一个weak的引用来观察它
reference = str;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"%@", reference); // Console: sunnyxx
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(@"%@", reference); // Console: (null)
}
测试以后发现三个方法中都输出了字符串”sunnyxx“,实际上sunnyxx对autorelease的分析还是很准确深刻的,输出结果不符合预期,是NSString在搞怪。
NSString是一个类簇(Class Clusters),最后生成的对象类型,取决于我们调用的初始化方法。不同的对象类型的管理方式不一样(在retainCount上有所体现)
类型 | 初始化后的retaincount |
---|---|
__NSCFConstantString | -1 |
__NSCFString | 1 |
__NSTaggedPointerString | -1 |
- 对于__NSCFConstantString,系统进行维护,retain和release不起作用(程序中内容相同的常量字符串只有一个)
- __NSCFString与其他oc对象一样维护retainCount
- __NSTaggedPointerString,retain/release不起作用
NSString *a = @"a";
NSString *c = [a copy];
NSLog(@"%p %p", a,c);//输出两个相同的地址,并没有真正的复制
example
__NSCFConstantString
@""格式的字符串
NSString *str1 = @"rainySue";//__NSCFConstantString
NSLog(@"str1:%d",[str1 retainCount]);// -1
stringWithString+__NSCFConstantString
NSString *str3 = [NSString stringWithString:@"str3"];//__NSCFConstantString
NSLog(@"str3:%d",[str3 retainCount]); // -1
__NSTaggedPointerString
case1
NSString *str2 = [NSString stringWithFormat:@"%s", "str2"];//__NSTaggedPointerString
NSLog(@"str2:%d",[str2 retainCount]); // -1
case2
NSString *a = @"a";
NSString *b = [[a mutableCopy] copy];//__NSTaggedPointerString
NSLog(@"b:%d",[b retainCount]); // -1
__NSCFString
通过stringWithFormat构造
NSString *str2_2 = [NSString stringWithFormat:@"%s,%d", "str2_2",22];//__NSCFString
NSLog(@"str2_2:%d",[str2_2 retainCount]); //1
stringWithString + stringWithFormat
NSString *str4_2 = [NSString stringWithString:[NSString stringWithFormat:@"hahah"]];//__NSCFString
NSLog(@"str4_2:%d",[str4_2 retainCount]); // 1
NSString *str4_1_1 = [NSString stringWithString:[NSString stringWithFormat:@"%s", "str2"]];
NSLog(@"str4_1_1:%d",[str4_1_1 retainCount]); //1
NSString *str4 = [NSString stringWithString:[NSString stringWithFormat:@"%s,%d", "str4",22]];//__NSCFString
NSLog(@"str4:%d",[str4 retainCount]); // 1
stringWithString+__NSTaggedPointerString对象
NSString *str2 = [NSString stringWithFormat:@"%s", "str2"];//__NSTaggedPointerString
NSString *str4_1_1 = [NSString stringWithString:[NSString stringWithFormat:@"%s", "str2"]];
NSLog(@"str4_1_1:%d",[str4_1_1 retainCount]); //1
stringWithString+__NSCFString对象
NSString *str2_2 = [NSString stringWithFormat:@"%s,%d", "str2_2",22];//__NSCFString
SString *str4_3 = [NSString stringWithString:str2_2];
NSLog(@"str4_3:%d",[str4_3 retainCount]); //2
NSMutableString对象
NSMutableString* str5 = [NSMutableString stringWithString:@"str5"];//__NSCFString
NSLog(@"str5:%d",[str5 retainCount]); //1
总结
- retainCount的不同本质上是因为NSString类簇返回的子类的不同,__NSCFConstantString 和__NSTaggedPointerString初始值为-1,__NSCFString为1
亦可通过方法来区分得到的字符串的类型
- @”“格式得到的为常量字符串
- stringWithFormat得到的可能为__NSCFConstantString或者__NSTaggedPointerString
stringWithString
- stringWithString+__NSCFConstantString得到__NSCFConstantString
- stringWithString+stringWithFormat得到__NSCFString,初始计数值为1
- stringWithString+__NSTaggedPointerString对象得到__NSCFString,初始计数值为1
- stringWithString+__NSCFString对象得到__NSCFString,初始计数值为2
PS:
当开成程序中viewDidLoad里的str指向__NSCFString时,在viewWillAppear和viewDidAppear中就能看到预期的NULL了。
NSString与奇怪的retainCount的更多相关文章
- IOS开发之关于NSString和NSMutableString的retainCount
1. 字符串常量 NSString *s = @"test"; NSLog(@"s:%lx",[s retainCount]); //fffffffffffff ...
- iOS中的retainCount
我们都知道iOS中采用引用计数的技术来管理内存,当一个对象没有任何一个地方引用的时候会自动释放,此时的retainCount为0,而且提供了一个-(NSInteger)retainCount的方法来获 ...
- iOS开发系列—Objective-C之Foundation框架
概述 我们前面的章节中就一直新建Cocoa Class,那么Cocoa到底是什么,它和我们前面以及后面要讲的内容到底有什么关系呢?Objective-C开发中经常用到NSObject,那么这个对象到底 ...
- iOS-几大框架的介绍
1.Objective-C之Foundation框架 概述 我们前面的章节中就一直新建Cocoa Class,那么Cocoa到底是什么,它和我们前面以及后面要讲的内容到底有什么关系呢?Objectiv ...
- iOS-Objective-C基础
一.Foundation框架 概述 我们前面的章节中就一直新建Cocoa Class,那么Cocoa到底是什么,它和我们前面以及后面要讲的内容到底有什么关系呢?Objective-C开发中经常用到NS ...
- [OC Foundation框架 - 17] copy语法
一个对象使用copy或mutableCopy方法可以创建对象的副本 1.copy 需要实现NSCopying协议 创建出来的是不可变副本,如NSString, NSArray, NSDictionar ...
- 关于NSString的retainCount的各种结果原因
转载:http://blog.csdn.net/onlyou930/article/details/6932529 http://www.cnblogs.com/celestial/archive/2 ...
- NSString,NSArray,NSNumber等类的继承问题
问题引入,我想给NSString类扩展一些新的方法.在Objective-C中可以有两种方法,一是继承,二是类别.本文先不讨论类别,我们用继承的方法试一下: @interface StringEx : ...
- 引用计数(retainCount)
ClassA.h: #import <Foundation/Foundation.h> @interface ClassA:NSObject { NSString *name; } -(v ...
随机推荐
- 使用jquery的append(content)方法的注意事项
append(content)函数:向每个匹配的元素内部追加内容. 如以下示例: 向所有段落中追加一些HTML标记. HTML 代码: <p>I would like to say: &l ...
- 如何将CKeditor编辑器的上传和thinkphp结合
转载:THINKPHP代码中 lxepoo的文章 有时候我们会发现,我们需要对上传文件进行日志记录,这样的记录通常写在LOG文件或数据库中,那么,通过TP本身的上传类,可以实现的,但是只能做到编辑器外 ...
- Java总结篇系列:类型转换/造型
Java中,经常可以遇到类型转换的场景,从变量的定义到复制.数值变量的计算到方法的参数传递.基类与派生类间的造型等,随处可见类型转换的身影.Java中的类型转换在Java编码中具有重要的作用.首先,来 ...
- java servlet手机app访问接口(二)短信验证
今天找了几个短信平台,其实最想使用的一个是sharesdk,使用它上面http api短信功能,不仅价格低,而且最少可以充值100RMB,但是审核过于严格,对应APP还必须集成他们的短信功能,而且要上 ...
- Java集合类中的哈希总结
JAVA集合类中的哈希总结 目 录 1.哈希表 2.Hashtable.HashMap.ConcurrentHashMap.LinkedHashMap.TreeMap区别 3.Hashtable.Ha ...
- jquery.form.js不能解决连接超时(timeout)的解决方法
最近在使用jquery.form.js提交包含文件的表单时,碰到了一个问题:当碰上网速较慢时,而我们又设置了timeout时,例如: var options = { timeout: 3000 //限 ...
- Java数组排序和查找
Java 1.2 添加了自己的一套实用工具,可用来对数组或列表进行排列和搜索.这些工具都属于两个新类的"静态"方法.这两个类分别是用于排序和搜索数组的Arrays,以及用于排序和搜 ...
- mysql经纬度查询并且计算2KM范围内附近用户的sql查询性能优化实例教程
之前很傻很天真地以为无非就是逐个计算距离,然后比较出来就行了,然后当碰到访问用户很多,而且数据库中经纬度信息很多的时候,计算量的迅速增长,能让服务器完全傻逼掉,还是老前辈的经验比我们丰富,给了我很大的 ...
- css知多少(7)——盒子模型
1. 引言 从这一节开始,我们就进入本系列的第三部分——css呈现.本部分将描述css在页面的几种布局和呈现的特性.包括两类:文字.块. 第一类——文字.这部分相对比较简单一些,例如设置字号.字体.颜 ...
- servle
基于HTTP协议下的,http请求和http响应. http请求------请求的是服务器中的地方. 1.servlet就是解析http请求和发送http响应. 2.servlet是是一个 ...