NSString的内存管理
来源:互联网 发布:淘宝旺旺卖家版2017 编辑:程序博客网 时间:2024/05/21 06:58
NSString引用计数很特殊
大多数情况下string的retainCount都是无限大的数。这是因为,字符串创建出来不是在堆上的,而是在常量区。常量区只要值相同,就是同一块内存。常量区的值在APP结束时才会释放,指向这块内存的指针不受引用计数限制。
下面有三种情况:
情况一: NSString*Str1 = [NSStringstringWithFormat:@"a%d",11];
NSLog(@"str1=%@",Str1);
NSLog(@"str1 count=%lu",[Str1retainCount]);
NSLog(@"str1地址:%p",Str1);
NSString *Str2 = [[NSStringalloc]initWithFormat:@"b%d",11];
NSLog(@"str2=%@",Str2);
NSLog(@"str2 count=%lu",[Str2retainCount]);
NSLog(@"str2地址:%p",Str2);
NSString *Str3 = [NSStringstringWithString:Str2];
NSLog(@"str3=%@",Str3);
NSLog(@"str3 count=%lu",[Str3retainCount]);
NSLog(@"str1 count=%lu",[Str1retainCount]);
NSLog(@"str1地址:%p",Str1);
NSString *Str2 = [[NSStringalloc]initWithFormat:@"b%d",11];
NSLog(@"str2=%@",Str2);
NSLog(@"str2 count=%lu",[Str2retainCount]);
NSLog(@"str2地址:%p",Str2);
NSString *Str3 = [NSStringstringWithString:Str2];
NSLog(@"str3=%@",Str3);
NSLog(@"str3 count=%lu",[Str3retainCount]);
NSLog(@"str3地址:%p",Str3);
017-05-02 19:22:48.490 TimerDemo[1097:52548] str1=a11
2017-05-02 19:22:48.490 TimerDemo[1097:52548] str1 count=18446744073709551615
2017-05-02 19:22:48.491 TimerDemo[1097:52548] str1地址:0x31316135
2017-05-02 19:22:48.491 TimerDemo[1097:52548] str2=b11
2017-05-02 19:22:48.491 TimerDemo[1097:52548] str2 count=18446744073709551615
2017-05-02 19:22:48.491 TimerDemo[1097:52548] str2 地址:0x31316235
2017-05-02 19:22:48.491 TimerDemo[1097:52548] str3=b11
2017-05-02 19:22:48.491 TimerDemo[1097:52548] str3 count=1
2017-05-02 19:22:48.491 TimerDemo[1097:52548] str2=b11
2017-05-02 19:22:48.491 TimerDemo[1097:52548] str2 count=18446744073709551615
2017-05-02 19:22:48.491 TimerDemo[1097:52548] str2 地址:0x31316235
2017-05-02 19:22:48.491 TimerDemo[1097:52548] str3=b11
2017-05-02 19:22:48.491 TimerDemo[1097:52548] str3 count=1
2017-05-02 19:22:48.491 TimerDemo[1097:52548] str3地址:0x100306f00
分析:str1,str2都是常量区的常量字符串,而str3创建返回的是一个string对象,有引用计数
情况二: NSString*Str1 = [NSStringstringWithFormat:@"asasasasasasasasaaa%d",11];
NSLog(@"str1=%@",Str1);
NSLog(@"str1 count=%lu",[Str1retainCount]);
NSLog(@"str1地址:%p",Str1);
NSString *Str2 = [[NSStringalloc]initWithFormat:@"assasasassasasasasb%d",11];
NSLog(@"str2=%@",Str2);
NSLog(@"str2 count=%lu",[Str2retainCount]);
NSLog(@"str2地址:%p",Str2);
NSString *Str3 = [NSStringstringWithString:Str2];
NSLog(@"str3=%@",Str3);
NSLog(@"str3 count=%lu",[Str3retainCount]);
NSLog(@"str1 count=%lu",[Str1retainCount]);
NSLog(@"str1地址:%p",Str1);
NSString *Str2 = [[NSStringalloc]initWithFormat:@"assasasassasasasasb%d",11];
NSLog(@"str2=%@",Str2);
NSLog(@"str2 count=%lu",[Str2retainCount]);
NSLog(@"str2地址:%p",Str2);
NSString *Str3 = [NSStringstringWithString:Str2];
NSLog(@"str3=%@",Str3);
NSLog(@"str3 count=%lu",[Str3retainCount]);
NSLog(@"str3地址:%p",Str3);
2017-05-02 19:48:43.269 TimerDemo[1190:60542] str1=asasasasasasasasaaa11
2017-05-02 19:48:43.270 TimerDemo[1190:60542] str1 count=1
2017-05-02 19:48:43.270 TimerDemo[1190:60542] str1 地址:0x1005036b0
2017-05-02 19:48:43.270 TimerDemo[1190:60542] str2=assasasassasasasasb11
2017-05-02 19:48:43.270 TimerDemo[1190:60542] str2 count=1
2017-05-02 19:48:43.270 TimerDemo[1190:60542] str2 地址:0x100700100
2017-05-02 19:48:43.270 TimerDemo[1190:60542] str3=assasasassasasasasb11
2017-05-02 19:48:43.270 TimerDemo[1190:60542] str3 count=2
2017-05-02 19:48:43.270 TimerDemo[1190:60542] str1 count=1
2017-05-02 19:48:43.270 TimerDemo[1190:60542] str1 地址:0x1005036b0
2017-05-02 19:48:43.270 TimerDemo[1190:60542] str2=assasasassasasasasb11
2017-05-02 19:48:43.270 TimerDemo[1190:60542] str2 count=1
2017-05-02 19:48:43.270 TimerDemo[1190:60542] str2 地址:0x100700100
2017-05-02 19:48:43.270 TimerDemo[1190:60542] str3=assasasassasasasasb11
2017-05-02 19:48:43.270 TimerDemo[1190:60542] str3 count=2
2017-05-02 19:48:43.270 TimerDemo[1190:60542] str3地址:0x100700100
情况三:NSMutableString*Str1 = [NSMutableStringstringWithFormat:@"a%d",11];
NSLog(@"str1=%@",Str1);
NSLog(@"str1 count=%lu",[Str1retainCount]);
NSLog(@"str1地址:%p",Str1);
NSMutableString*Str2 = [[NSMutableStringalloc]initWithFormat:@"b%d",11];
NSLog(@"str2=%@",Str2);
NSLog(@"str2 count=%lu",[Str2retainCount]);
NSLog(@"str2地址:%p",Str2);
NSMutableString*Str3 = [NSMutableStringstringWithString:Str2];
NSLog(@"str3=%@",Str3);
NSLog(@"str3 count=%lu",[Str3retainCount]);
NSLog(@"str1 count=%lu",[Str1retainCount]);
NSLog(@"str1地址:%p",Str1);
NSMutableString*Str2 = [[NSMutableStringalloc]initWithFormat:@"b%d",11];
NSLog(@"str2=%@",Str2);
NSLog(@"str2 count=%lu",[Str2retainCount]);
NSLog(@"str2地址:%p",Str2);
NSMutableString*Str3 = [NSMutableStringstringWithString:Str2];
NSLog(@"str3=%@",Str3);
NSLog(@"str3 count=%lu",[Str3retainCount]);
NSLog(@"str3地址:%p",Str3);
2017-05-02 19:39:39.160 TimerDemo[1120:56551] str1=a11
2017-05-02 19:39:39.161 TimerDemo[1120:56551] str1 count=1
2017-05-02 19:39:39.161 TimerDemo[1120:56551] str1 地址:0x100503500
2017-05-02 19:39:39.161 TimerDemo[1120:56551] str2=b11
2017-05-02 19:39:39.161 TimerDemo[1120:56551] str2 count=1
2017-05-02 19:39:39.161 TimerDemo[1120:56551] str2 地址:0x100200170
2017-05-02 19:39:39.161 TimerDemo[1120:56551] str3=b11
2017-05-02 19:39:39.161 TimerDemo[1120:56551] str3 count=1
2017-05-02 19:39:39.161 TimerDemo[1120:56551] str1 count=1
2017-05-02 19:39:39.161 TimerDemo[1120:56551] str1 地址:0x100503500
2017-05-02 19:39:39.161 TimerDemo[1120:56551] str2=b11
2017-05-02 19:39:39.161 TimerDemo[1120:56551] str2 count=1
2017-05-02 19:39:39.161 TimerDemo[1120:56551] str2 地址:0x100200170
2017-05-02 19:39:39.161 TimerDemo[1120:56551] str3=b11
2017-05-02 19:39:39.161 TimerDemo[1120:56551] str3 count=1
2017-05-02 19:39:39.161 TimerDemo[1120:56551] str3地址:0x1005038a0
小总结:
NSString是“不可变(immutable)”的类型
1>直接以“@”开头创建的字符串,其实就是一个字符串常量,运行时会检测这个字符串是否已经存在,存在的话,就直接将这个字符串的地址赋给变量;不存在的话,则创建,再赋值。
2>用stringWithstring:@“”创建会自动转为第一种情况,
stringWithstring:str对象 创建,返回的是一个string对象,在堆上分配空间,有引用计数
3>用stringWithFormat:@“”创建,如果@“”比较短,就在常量区分配,无引用计数
如果字符串比较长,就是在堆上分配,有引用计数
4>NSMutableString是实打实的对象,遵循引用计数规则,在堆上分配内存
编译器、runtime充分利用了NSString是“不可变(immutable)”类型这个特点,只要字符串内容一致,就不会分配新的内存储存,字符串在程序中使用量非常大,这么做可以大大节省内存,提升性能。
NSString *str= @"dddd";
[str release];
NSLog(@"str is %@",str);
常量区的字符串中途不会被销毁,所以不会产生向废弃对象发送消息引起崩溃的情况。
NSString *str= @"dddd";
while(YES) {
str= @"aaaaaaaaa";
NSLog(@"%@ %d",str,str.retainCount); }
内存不会涨
NSString *str= @"dddd";
while(YES) {
str= @"aaaaaaaaa";
NSLog(@"%@ %d",str,str.retainCount); }
内存暴涨
0 0
- NSString的内存管理
- NSString的内存管理
- NSString奇葩的内存管理
- NSString的内存管理问题
- NSString的内存分配及管理
- NSString的内存分配及管理
- Objective-C -- NSString的内存管理
- NSString的内存分配及管理
- NSString的内存分配及管理
- 一个关于NSString内存管理的问题
- NSString 类的内存管理问题
- NSString 内存管理问题
- NSString 字符串管理内存
- NSString内存管理
- 亲测 nsstring 内存管理
- NSString内存管理
- OC学习笔记之NSString类的内存管理小记
- NSString 的内存问题
- 随机过程基本概念
- android自定义View之仿通讯录侧边栏滑动,实现A-Z字母检索
- NandFlash驱动超详细分析
- 淘宝网分布式存储技术视频
- 2016-2017学年第二学期C++第五章(2)
- NSString的内存管理
- Xargs用法详解
- python读取文件并绘制三维点图
- CyclicBarrier(int parties, Runnable barrierAction) 详解
- sublime的快捷键
- 秒杀系统设计详解
- java转型
- MongoDB学习记录03-MongoDB查询(java-driver)
- Learning Spark笔记7-聚合