标签:
1.所谓使用类的静态方法创建对象,就是指使用类名调用一次它的静态方法(非显式调用alloc)便可以得到一个新建的对象,比如下面两个例子:
NSString* str1 = [NSString stringWithString:@"hello world"];
NSMutableString* str2 = [NSMutableString stringWithString:@"hello world"];
2. 第一个例子是使用字符串的字面常量"hello world"创建一个NSString对象,已知常量在编译期分配,存放在程序的数据区(常量区),全局唯一且不可改变;因为NSString对象是不可变的,所以str1直接指向数据区的"hello world",而不会在内存中创建副本;而str2是可变的字符串对象,因此需要将常量“hello world”的内容拷贝到内存,这样才支持对字符串内容的修改。因此,str1的创建基本上不增加内存开销,而str2的创建会增加内存开销。
3.NSString的静态方法stringWithString会创建一个对象,为了保证该对象能够被正确释放,在返回该对象之前,会调用对象的autorelease方法,将对象的释放操作交给了外层的自动释放池对象;而对应的经典的alloc+init方式创建的对象,不会调用autorelease.因为当你显式使用alloc时,ARC会给你添加相应的release操作,所以这种方式创建的对象可以被正常释放。
4.内存泄露的例子
while(YES) { NSMutableString* str = [NSMutableString stringWithString@"hello world"]; }
使用死循环是为了使泄露的结果更更显,如果每次操作的数据很大,那效果更明显。
5.泄露的原因
每次创建对象str,都会开辟一块新内存存放数据"hello world";而释放的方式是autorelease,然而在此循环中接触不到外层的自动释放池,因此所有创建的对象都没有被及时释放掉,因此内存占用会越来越大,效果如同内存泄露。
6.解决方式
一:循环内使用自动释放池,及时释放掉对象(不推荐,增加自动释放池对象创建和销毁开销)
while(YES) { @autorelease{ NSMutableString* str = [NSMutableString stringWithString@"hello world"]; } }
二:使用经典的alloc+init方式创建对象(推荐,效率高而无副作用)
while(YES) { NSMutableString* str = [[NSMutableString alloc]initWithString:@"hello world"]; }
三:如果可能,使用NSString代替NSMutableString(不推荐,勉强规避)
while(YES) { NSString* str = [NSString stringWithString@"hello world"]; }
标签:
原文地址:http://www.cnblogs.com/guoxiaoqian/p/4394487.html