搞定IPhone应用的内存泄露

来源:未知 责任编辑:智问网络 发表时间:2013-10-30 11:07 点击:

IPhone上木有垃圾回收,动态申请的内存要自己记得释放,此文自己总结一下可能出现内存泄露的各种情况,以及检测方法。
 
内存泄露说白了,就是有这样一块动态申请的内存,但木有任何一个指针指向它。
 
举例来说,在C++中:
 
1. MyClass * foo = new MyClass; 
2. foo = NULL;
 
类似地在objective-C中:
 
1. MyClass *foo = [[MyClass alloc] init]; 
2. foo = nil;//内存泄露了!
 
 
或者有这样一个类:
 
1. @interface Foo : NSObject 
2. {} 
3. @end 
4. 
5. @implementation Foo 
6. -(id) init 
7. { 
8.         if ((self = [super init])) { 
9.                 NSMutableString * string = [[NSMutableString alloc] initWithString:@"Leaker!!!"]; 
10.                 string = nil;//泄露了!这句之后那个字符串对象应用退出之前不会被释放。
11.         } 
12.         return self; 
13. } 
14. - (void) dealloc 
15. { 
16.         [super dealloc]; 
17. } 
18. @end
 
出现内存泄露会怎样?
答:很小的泄露,没事!应用退出的时候所用内存都会被清理,包括泄露的,而且IPhone应用不会申请到共享内存,不会波及到整个系统,不会出现系统范围的内存泄露。要是泄露的比较多,而且反复不停地出现内存泄露,顶多应用崩溃掉。不过想发布到AppStore的话,有内存泄露一般会被苹果拒绝……。
 
先来看看IPhone里内存是怎么管理的,首先:木有自动垃圾回收!其次:有引用记数!
NSObject对象有个属性:retainCount,所以所有对象都要继承自NSObject,才有统一的引用计数…。
 
然后牢记记住下面8件事:
• 1 这个retainCount == 0的时候,对象的dealloc方法会被调用,对象就被释放了。
• 2 永远不要显示调用dealloc方法
• 3 [obj retain]; // obj.retainCount++ 引用记数+1
• 4  [obj release]; // obj.retainCount-- 引用记数-1
• 5 MyClass * obj = [[MyClass alloc] init];// obj.retainCount = 1 初值为1
• 6 对于有retain特性的属性比如下面这个:
1. @interface MyClass : NSObject { 
2.   NSObject* foo; 
3. } 
4. @property (noatomic,retain) NSObject * foo; 
5. @end 
6. 
7. @implementation MyClass 
8. @synthesize foo; 
9. ... 
10.   //下面两行正确的写法 
11.   self.foo = bar;// [foo release]; foo = bar; [foo retain]; 会发一个release给原来的对象,发一个retain 给新对象 
12.   self.foo = nil;// [foo release]; 会发一个release 消息给对象 
13. 
14.   //下面一行写法不对 
15.   foo = bar;// 没发release给foo 没发retain给bar ,这种写法是不对的。 
16. ... 
17. @end
  参考:
苹果的文档 和 具体实现的解释

• 7 对于stringWithString 这种方法创造的对象,一个Runloop结束时,对象会被发送一个release消息,需要注意的有两点,一是注意理解Runloop,避免Runloop结束后对象被释放了却又使用对象,二是 如果用instruments工具检测内存泄露,这种使用autorelease的情况也会被当做内存泄露处理,注意识别……。
• 8 对于NSMutableArray这种类,当addObject的时候,相应被加入array中的那个对象的引用计数会被+1,当array本身释放时,它会先给array中的所有对象发一个release消息。www.2cto.com
 
可以用Instruments检测内存泄露,里各种各样的工具,用Leaks。
用起来很简单:用Xcode(4.3)打开相应的项目,Product->Profile,选Leaks工具。 之后会动态地记录应用运行过程中,有哪些地方出现内存泄露。 需要注意的地方有二:
1 对于被autorelease的对象,Leak工具也会视其为泄露,自己知道没问题就行。
2 记得点开Extended Detail ,对于每一出泄露,可以在这里看到调用堆栈,双击调用堆栈中的某一项,可以直接定位到代码,便于查错跟修改。 情况如下两个图:





作者:dawn110110

    发表评论
    请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
    用户名: 验证码:点击我更换图片
    最新评论 更多>>

    推荐热点

    • Lexical or Preprocessor Issue 'xxx.h
    • ios学习笔记(二)xcode 4.3.2下实现基本交互
    • ios版本的helloworld
    • iphone(object-c) 内存管理(3) 有效的内存管理 前半部分
    • ios学习笔记(一)xcode 4.3.2下创建第一个ios项目
    • IOS类似iphone通讯录TableView的完整demo【附源码】
    • UITableView一些方法
    • [iPhone中级]iPhone团购信息客户端的开发 (二)
    • 如何为Iphone应用创建启动界面
    网站首页 - 友情链接 - 网站地图 - TAG标签 - RSS订阅 - 内容搜索
    Copyright © 2008-2015 计算机技术学习交流网. 版权所有

    豫ICP备11007008号-1