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实用的语法总结
1.关于页面元素的引用 通过jquery的$()引用元素包括通过id.class.元素名以及元素的层级关系及dom或者xpath条件等方法,且返回的对象为jquery对象(集合对象),不能直接调用do ...
- asp.net(c#)将彩色图片变灰阶图片
代码如下: using System; using System.Collections; using System.Configuration; using System.Data; using S ...
- iOS阶段学习第一天笔记(Mac终端的操作)
前言部分 原本从事的是.NET开发,一直在要不要转iOS 中犹豫徘徊,经过复杂的内心挣扎终于鼓起勇气辞职脱产学习iOS;希望通过四个月的 学习后能够拿到理想的薪资.以下是学习过程中的学习笔记,为了方便 ...
- Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition
Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...
- TestNG官方文档中文版(4)-运行TestNG
4 - 运行TestNG TestNG可以以不同的方式调用: * Command line * ant * Eclipse * IntelliJ's IDEA 1) 命令行 假 ...
- 设计人员应该看的15个很酷的 iOS 8 设计
苹果新一代智能手机 iPhone 6 发布已经有一段时间了,一些创意设计师已经开始在设计中采用 iOS 8 设计理念.当然,其中有些是对于未来的展望和大胆的设计.我在这里收集了15个很酷的 iOS 8 ...
- CodePen 作品秀:Canvas 粒子效果文本动画
作品名称——Shape Shifter,基于 Canvas 的粒子图形变换实验.在页面下方的输入框输入文本,上面就会进行变换出对应的粒子效果文本动画. CodePen 作品秀系列向大家展示来自 Cod ...
- CSS中兼容的一面-----Hack
国庆了,出去玩耍,也有好长时间没有更新博客了.. 今天就和大家共享一篇技术博文吧.. CSS中兼容的一面-----Hack技术大全 兼容范围: IE:6.0+,FireFox:2.0+,Opera 1 ...
- Python 操作 MySQL 之 pysql 与 ORM(转载)
本文针对 Python 操作 MySQL 主要使用的两种方式讲解: 原生模块 pymsql ORM框架 SQLAchemy 本章内容: pymsql 执行 sql 增\删\改\查 语句 pymsql ...
- [转]DevExpress v13.2 Beta版重要更新
昨日,DevExpress隆重宣布发布v13.2.3测试版,想抢先尝鲜的朋友可以在这里下载哦.希望使用DevExpress旧版本的朋友,看到这些更新后能尽快更新你的代码,以免造成不必要的麻烦. Das ...