这个系列打算写一些我对iPhone开发内存管理的理解。是建立在读者对Objective C的内存管理已经有一定理解的基础上,内容将包括实践准则,autorelease原理剖析,内存泄露的调试等。如果您对Objective C内存管理不太了解,建议先读一下Vince Yuan的这个教程。
在进行iPhone开发时, 内存管理是个相对比较难以理解的东西。Objective-C 使用了一种介于C#和C++之间的内存管理机制。C#是基于Mark-sweep的GC,C++基本上是程序员自己负责分配和释放。Ojbective-C,是程序员来负责Mark(通过Release, retain, alloc)计数, 系统来进行分配和释放。下面是一些准则,可以避免内存泄露和使用已释放的内存造成程序crash。
1)你必须为你自己创建的Object负责。包括alloc, newObject,mutableCopy 等,或者是你调用过retain的object。对于这些Object, 你必须调用release 或autorelease
2)对于其它函数返回的Object,你不能release它,原则上应该由被调用的函数来负责。e.g. NSString str = [NSString stringWithFormat:]. 你自己写的函数也最好遵循这个准则,谁申请,谁释放,而不要让调用者来释放。
3)如果你要在某个对象的property里存储另外一个对象,你必须retain或者copy它,避免它被别人release。
@property(retain)。。 这里的retain关键字会自动做这个事情。如果你自己声明set方法就要手动做这个事情。
4)autorelease 意味着该object会由系统在某个时机release它。
5)确保你返回的object是有效的。在如下例子中, 因为heisenObject 被从array中remove掉,会有一个release message到heisenObject,如果没有其它人reference它, heisenObject会被dealloc 掉。
- heisenObject = [array objectAtIndex:n];
- [array removeObjectAtIndex:n];
- // heisenObject could now be invalid.
6) weak reference. 如下图, Document 类中Page property 指向Page类的对象, page类中Parent property指向Document, 这样如果互相之间的retain count都是1的话,那么这两个object永远不会被Dealloc。 解决办法是把page.parent变为weak reference,也就是说, page.parent并不retain Document。 UITableView.datasource, notification observers, delegates, outline view items 等都是week reference。
原文标题:Objective C内存管理进阶(一):实践准则
链接:http://www.cnblogs.com/MobileDevelop/archive/2010/07/19/1779755.html
【编辑推荐】