现在的位置: 首页 > 综合 > 正文

iOS内存小论

2014年08月29日 ⁄ 综合 ⁄ 共 1235字 ⁄ 字号 评论关闭

在cocoaChina上看到了一个贴子,关于内存的,原贴在:

http://www.cocoachina.com/bbs/read.php?tid=96523&page=1

NSString *str =[[NSString alloc] initWithString:@"4321"]; 
 str = @"123"; 
 
     
  NSLog(@"%@",str); 
  [str release]; 

原贴问这样的代码是否会内存泄漏?回贴中有人指出不会发生内存泄漏,本人觉得在这儿还真不会发生内存泄漏,贴子中没有说明原因,我在这儿分析一下。

NSString *str =[[NSString alloc] initWithString:@"4321"];   这一句有两个意思, 编译器在堆上分配一个空间地址存放@"4321",比如地址是0xbbbb,运行时在栈上分配一个内存地址如0xaaaa, 它里面存放的值是0xbbbb.  此时retrain count是1
 str = @"123";    编译器在堆上分配一个内存空间0xcccc存放@"123",并将内存0xaaaa中的值修改为0xcccc
 
     
NSLog(@"%@",str);    输出当然是0xcccc里的值,即123
[str release];    这一句会自动被编译器过滤掉,即不起作用,原因是str在此时指向的是NSConstantString。而常量字符串是不需要手动release的,就算你手动release也不会出错,我就认为是编译器自动过滤掉。不信你可以试试以下代码,绝对不会出错。

NSString *str = @"test";
[str release];

为何我说会被过滤掉,网上有人说:http://stackoverflow.com/questions/4782477/ios-memory-management-to-release-a-string-or-not

这样一来原先alloc的内存空间0xaaaa里就一直存有值是0xcccc,  直到该区域的栈回收的时候。而它原先指向的地址是0xbbbb,它是常量地址,常量地址是不面需要手动release的,所以本人认为就算写这样的代码也不会造成内存泄漏。

NSString *str = [[NSString alloc] initWithString:@"4321"];

//不要这行[str release];

两个地址,堆地址与栈地址,堆地址是常量,不需要手动释放,栈地址会自动回收,NSString比较特殊,如果是NSData,NSMutableString这些就不行了,得必须手动release。因为这些在堆上的内存空间需要手动release。所以我们要有好的习惯,按照官网的内存管理来开发。有alloc, copy, retrain就得与之对应release.

本来想看一下代码汇编,弄个明白,看了一下,我的天啦,与windows下的不一样,看求不懂,好像汇编有两个标准,他们走的路线不一样。

这只是本人个人见解,有误还请指正。

抱歉!评论已关闭.