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 ...
随机推荐
- 利用chrome调试JavaScript代码
看见网上很多人问怎么用chrome调试JavaScript代码,我也对这个问题抱着疑问,但是没有找到一篇能用的中文文章(可能我的google有问题),也不知道怎么点出一篇E文的,感觉作者写得不错,所以 ...
- 走进异步世界-犯傻也值得分享:ConfigureAwait(false)使用经验分享
在上周解决“博客程序异步化改造之后遭遇的性能问题”的过程中,我们干了一件自以为很有成就感的事——在表现层(MVC与WebForms)将所有使用await的地方都加上了ConfigureAwait(fa ...
- 基于吉日嘎底层架构的通用权限管理Web端UI更新:参考DTcms后台界面
经一周的研究学习,看了国内的H+.HUI等,国外的PaperDashboardPro.Make.Metronic BootStrap等,最终选定用一个轻量的,适合中国人的,来自DTcms的后台管理UI ...
- 清除svn账户账号密码
1. 2. 3. 4. 5.再次访问时,会弹出要求输入用户名和密码:只是清除记住的用户名和密码.
- mybaits 框架运用
支持普通 SQL 查询,存储过程和高级映射的ORM持久层框架.以一 个 SqlSessionFactory 对象的实例为核心. 从 XML 中构建 SqlSessionFactory configur ...
- 点我吧工作总结(技术篇) zookeeper
我思故我在,提问启迪思考! 1.什么是zookeeper? 2.zookeeper与dubbo.springMVC之间的协同工作? http://doc.okbase.net/congcong68/a ...
- Verilog学习笔记认识提升篇(一)...............时序的基本概念(待补充)
建立和保持时间: 建立时间(Tsu)是指在时钟上升沿到来之前数据必须保持稳定的时间,保持时间(Th)是指在时钟上升沿到来以后数据必须保持稳定的时间.一个数据需要在时钟的上升沿被锁存,那么这个数据就必须 ...
- Selenium学习笔记之外部化相关测试数据---xml
我们也可以用xml来定义一个信息更为丰富的UIMap.xml文件,比如,额外还添加控件所属的页,控件的类型,然后解析构建一个XMLParser类来读取相应的值. <?xml version=&q ...
- JSESSIONID与SESSION
用spring security的时候遇到了一个很诡异的问题: 已经登录的用户,而且没有标记remember-me,在重启服务器之后还会显示已经登录状态 这就严重啦,这样子如果要在session中储存 ...
- 20款时尚的 WordPress 博客主题【免费下载】
在这篇文章中,我们收集了20款时尚的 WordPress 博客模板.WordPress 作为最流行的博客系统,插件众多,易于扩充功能.安装和使用都非常方便,而且有许多第三方开发的免费模板,安装方式简单 ...