NSString的内存管理

xiaoxiao2021-02-27  385

NSString引用计数很特殊 大多数情况下string的retainCount都是无限大的数。这是因为,字符串创建出来不是在堆上的,而是在常量区。常量区只要值相同,就是同一块内存。常量区的值在APP结束时才会释放,指向这块内存的指针不受引用计数限制。 下面有三种情况: 情况一: NSString *Str1 = [ NSString stringWithFormat : @"a%d" , 11 ];         NSLog ( @"str1=%@" ,Str1);         NSLog ( @"str1 count=%lu" ,[Str1 retainCount ]);         NSLog ( @"str1 地址: %p" ,Str1);                 NSString *Str2 = [[ NSString alloc ] initWithFormat : @"b%d" , 11 ];         NSLog ( @"str2=%@" ,Str2);         NSLog ( @"str2 count=%lu" ,[Str2 retainCount ]);         NSLog ( @"str2 地址: %p" ,Str2);                 NSString *Str3 = [ NSString stringWithString :Str2];         NSLog ( @"str3=%@" ,Str3);         NSLog ( @"str3 count=%lu" ,[Str3 retainCount ]);         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] str3 地址:0x100306f00 分析:str1,str2都是常量区的常量字符串,而str3创建返回的是一个string对象,有引用计数 情况二: NSString *Str1 = [ NSString stringWithFormat : @"asasasasasasasasaaa%d" , 11 ];         NSLog ( @"str1=%@" ,Str1);         NSLog ( @"str1 count=%lu" ,[Str1 retainCount ]);         NSLog ( @"str1 地址: %p" ,Str1);                 NSString *Str2 = [[ NSString alloc ] initWithFormat : @"assasasassasasasasb%d" , 11 ];         NSLog ( @"str2=%@" ,Str2);         NSLog ( @"str2 count=%lu" ,[Str2 retainCount ]);         NSLog ( @"str2 地址: %p" ,Str2);                 NSString *Str3 = [ NSString stringWithString :Str2];         NSLog ( @"str3=%@" ,Str3);         NSLog ( @"str3 count=%lu" ,[Str3 retainCount ]);         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] str3 地址:0x100700100 情况三: NSMutableString *Str1 = [ NSMutableString stringWithFormat : @"a%d" , 11 ];         NSLog ( @"str1=%@" ,Str1);         NSLog ( @"str1 count=%lu" ,[Str1 retainCount ]);         NSLog ( @"str1 地址: %p" ,Str1);                 NSMutableString *Str2 = [[ NSMutableString alloc ] initWithFormat : @"b%d" , 11 ];         NSLog ( @"str2=%@" ,Str2);         NSLog ( @"str2 count=%lu" ,[Str2 retainCount ]);         NSLog ( @"str2 地址: %p" ,Str2);                 NSMutableString *Str3 = [ NSMutableString stringWithString :Str2];         NSLog ( @"str3=%@" ,Str3);         NSLog ( @"str3 count=%lu" ,[Str3 retainCount ]);         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] 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); } 内存暴涨
转载请注明原文地址: https://www.6miu.com/read-2372.html

最新回复(0)