原文地址:http://blog.itotem.com.cn/?p=22
- alloc, copy, retain会把引用计数+1
- release会把引用计数-1
- 局部变量如果初始化时不是autorelease的,要及时调用release释放,并且赋值为nil否则引用仍然存在导致下次无法用nil做是否有值的判断
- 实例变量要在每次赋值时要先释放当前引用的对象再赋值,并retain一下保证引用计数为1
- 对于有retain参数的property,直接使用”.”赋值时系统会自动释放当前引用对象再赋值,并自动retain一下
- dealloc中要对所有实例变量调用release,对于有retain参数的property只需要调用self.theProperty = nil即可,系统会去做释放
- delegate的property通常设为assign,如果设为retain的话会有循环引用的问题,比如aView.delegate = self时会把self retain一下,在aView的dealloc中会把delegate release,但是由于self的引用永远不会小于1,所以导致aView和self的dealloc永远都不会被执行,都永远驻留内存造成泄露。所以如果要设为retain的话一定要确保不会造成循环引用问题。
- 在UIViewController中的viewDidUnload中要释放掉局部变量,调用release并设为nil,有时系统收到内存警告时会自动调用这个函数来释放一些内存空间
- 系统内存警告的回调中要释放掉内存中的缓存和其他可释放的东西,以免造成crash
- 使用UITableView时要把cell设置为重用的,并且要确保确实写得是重用的,有的人写完的结果相当于还是每次都重建cell,导致效率低下
- 使用UIScrollView时要自己控制释放掉目前不显示的内容,尤其是图片,考虑图片大小和浏览效果可以加载当前显示页两边的3-5页内容
- 图片需要做缓存,尤其是本地文件系统缓存,可以放到Library/Cache目录中,这个目录系统有专用的常量来获取,比如:
这里是一个小例子阐释前几条基本原则:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | - (void)aFunction{ //创建一个局部变量view UIView *view = [[UIView alloc] init]; // 赋值给实例变量theView [theView release]; //先释放一下当前引用的变量 theView = [view retain]; //给实例变量赋值时需要retain一下 // 如果theView是一个有retain属性的property self.theView = view; //不需要先释放,也不需要调用retain,系统会自动做,所以一定不能这样写self.view = [[UIView alloc] init];,这样的话创建的view会被retain两次,造成泄露,对于这种可以先创建一个局部变量,给self.view赋值后再释放 [view release]; //要及时释放局部变量 } - (void)dealloc{ //释放局部变量 [theView release]; //如果theView是一个有retain属性的property,也可以这样写 self.theView = nil; [super dealloc]; } |