[转载] iphone 很有意思的NSString 和 Autorelease
原文摘自:http://www.cnblogs.com/jifsu/archive/2011/09/09/2172863.html
一个方法,返回一个NSString对象,在事件中调用方法.并尝试release 方法返回的NSString对象.
-( NSString *) createNewString{ |
//情况1 |
return [[[ NSString alloc] initWithFormat:@ "%@" ,@ "1223344" ] autorelease]; |
//情况2 |
return [[[ NSString alloc] initWithString:@ "1223344" ] autorelease]; |
// 情况3 |
return @ "1223344" ; |
} |
//调用方法,在事件中 |
- ( IBAction )TouchDown:( id )sender { |
NSString * str = [ self createNewString]; |
NSLog (@ "输出1 , count : %d" , [str retainCount]); |
[str release]; |
NSLog (@ "输出2 , count : %d" , [str retainCount]); |
} |
情况1 :
2011-09-08 21:33:38.817 AutoRelease[718:b303] 输出1 count : 1
2011-09-08 21:33:38.819 AutoRelease[718:b303] *** -[CFString retainCount]: message sent to deallocated instance 0x4e50c60
此时xcode断点停留在 输出2... 本来以为是输出2抛错. 理解为: 一个被回收的对象,不能执行方法retainCount . (单纯被回收 和 nil 是否有区别下次学习)
注释 输出2
结果为 :
2011-09-08 21:35:02.690 AutoRelease[745:b303] 输出1 count : 1
2011-09-08 21:35:02.692 AutoRelease[745:b303] *** -[CFString release]: message sent to deallocated instance 0x6895940
断点已经跑到main方法中去了. 此时确定为 [str release]; 方法抛错. 理解为: 对于一个 autorelease 的对象.不能手工进行 release操作.
修改一下调用方法:
- (IBAction)TouchDown:(id)sender {
NSString* str = [[self createNewString] retain];
NSLog(@"输出1 count : %d" , [str retainCount]);
[str release];
NSLog(@"输出2 count : %d" , [str retainCount]);
}
此时方法执行通过,无异常.输出为:
2011-09-08 21:40:42.029 AutoRelease[804:b303] 输出1 count : 2
2011-09-08 21:40:42.030 AutoRelease[804:b303] 输出2 count : 1
理解为: 当你需要操作 一个被autorelease的对象时. 可以首先 retain 他,然后在不在需要他的时候,release他 . (这个是对象所有权的问题) .. retain == 计数器+1
----------------------------------- ----------------------------------- ----------------------------------- -----------------------------------
情况2 , 情况 3 : 方法 在修改前 和修改后2种代码下,都能运行过去.
输出都为:
2011-09-08 21:49:16.993 AutoRelease[864:b303] 输出1 count : 2147483647
2011-09-08 21:49:16.995 AutoRelease[864:b303] 输出2 count : 2147483647
理解为: initWithString:@"1223344" ,创建了一个 常量 字符串.并被系统限定为不可release和retain的对象. 有点类似 苹果推荐的单例模式
注: 2147483647 是 UINT_MAX 的值
如果方法返回 return [[[NSString alloc] init] stringByAppendingString:@"Hello World!"];
这个里面会存在内存泄露吗??? 继续研究....
可以参考的:http://stackoverflow.com/questions/1390334/nsstring-retain-count