【前情提要】 内存分配地址:栈区地址最高,堆区次之,常量区再次之
1、NSString等Foundation框架中类的内存管理 1)如果你需要的字符串在常量池中已经存在,则不会分配内存空间 【使用字符串的时候】@”“,stringWithString, alloc initWithString都是在常量区 【常量区的对象引用计数是无符号的最大值,如果用%ld输出是-1,用retain和release是没有用的】 【使用initWithFormat时字符串在堆区,前面有alloc时需要release,如果没有系统会自动消灭,不用理会】
例如: - @autoreleasepool {
- int a = 1;//栈区
- /*如果你需要的字符串在常量池中已经存在,则不会分配内存空间
- 【使用字符串的时候】@”“,stringWithString, alloc initWithString都是在常量区
- */
- NSString *str1 = @"abc";//常量区
- NSString *str2 = [NSString stringWithString:@"abc"];//常量区
- NSString *str3 = [[NSString alloc] initWithString:@"abc"];//常量区
- /*【使用initWithFormat时字符串在堆区,前面有alloc时需要release,如果没有系统会自动消灭,不用理会】
- */
- NSString *str4 = [NSString stringWithFormat:@"abc"];//堆区
- NSString *str5 = [[NSString alloc] initWithFormat:@"abc"];//堆区
-
- NSLog(@"a = %d, address = %p, retainCount = %lu",a,&a, str1.retainCount);
- NSLog(@"str1 = %@, address = %p, retainCount = %lu",str1,str1, str1.retainCount);
- NSLog(@"str2 = %@, address = %p, retainCount = %lu",str2,str2, str2.retainCount);
- NSLog(@"str3 = %@, address = %p, retainCount = %lu",str3,str3, str3.retainCount);
- NSLog(@"str4 = %@, address = %p, retainCount = %lu",str4,str4, str4.retainCount);
- NSLog(@"str5 = %@, address = %p, retainCount = %lu",str5,str5, str5.retainCount);
- }
复制代码
打印结果: 2015-10-06 16:12:59.962 MRCDemo[2146:303] a = 1,address = 0x7fff5fbff93c, retainCount = 18446744073709551615 2015-10-06 16:12:59.964 MRCDemo[2146:303] str1 = abc,address = 0x1000023a8, retainCount = 18446744073709551615 2015-10-06 16:12:59.965 MRCDemo[2146:303] str2 = abc,address = 0x1000023a8, retainCount = 18446744073709551615 2015-10-06 16:12:59.965 MRCDemo[2146:303] str3 = abc,address = 0x1000023a8, retainCount = 18446744073709551615 2015-10-06 16:12:59.966 MRCDemo[2146:303] str4 = abc,address = 0x100109c80, retainCount = 1 2015-10-06 16:12:59.966 MRCDemo[2146:303] str5 = abc,address = 0x10010a660, retainCount = 1
【疑问1】 NSString *str3 = [[NSString alloc] initWithString:@"abc"];为什么这样也是alloc,但是却是在常量区。因为这种用法被Xcode特殊处理过。同样地NSString *str2 = [NSString stringWithString:@"abc"];这种用法也是在常量区的。 【疑问2】 NSString *str4 = [NSString stringWithFormat:@"abc"];这种用法创建的字符串对象也是在堆区,但是一旦使用release就会挂掉。因为,这种是由系统自动清理的,不需要手动release。而NSString *str5 = [[NSString alloc] initWithFormat:@"abc"];这种因为手动调用了alloc方法,因此需要手动release
【危险用法】:使用retainCount作为循环条件的判断 - while ([str2 retainCount] > 0) {
- [str5 release];
- }
复制代码
这种做法有可能导致死循环,不要使用retainCount作为循环判断条件
|