应用程序内存管理是在您的程序运行时分配内存,使用它并在完成时释放内存的过程。一个写得很好的程序尽可能少地使用内存。在Objective-C中,它也可以被看作是将有限内存资源的所有权分配给许多数据和代码段的一种方式。

OC提供两种内存管理方式:手动管理内存MRR(manual retain-release),自动自动引用计数ARC。ARC使用和MRR一样的引用计数方法,在编译器加入管理内存的方法。

不正确的内存管理会造成两个问题:1,释放或者覆盖正在使用的数据,这导致了内存破坏,是一种典型的程序崩溃方式,更糟糕的是,可能会破坏用户数据;2,不在使用的内存,没有被释放导致内存泄漏。内存泄漏会让你的程序白白初始化很多不用的内存,降低系统性能,导致程序被终止。

基本的内存管理规则

内存管理模型基于对象所有权。任何对象都可能拥有一个或多个所有者。只要一个物体至少有一个所有者,它就会继续存在。如果一个对象没有所有者,则运行时系统将自动销毁它。

• You own any object you create,你自己拥有所有你自己创建的对象
• You create an object using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” (for example, alloc, newObject, or mutableCopy).
• You can take ownership of an object using retain,你可以使用retain关键字拿到对象所有权
• 接收到的对象通常保证在接收到的方法内保持有效,并且该方法还可以安全地将该对象返回给其调用者。在两种情况下使用retain关键字:1,在访问器方法或init方法的实现中,将要存储的对象的所有权作为属性值; 2,防止某个对象作为其他操作的副作用而失效
• 当你不需要它的时候,你必须放弃这个对象的所有权(使用 release关键字或者 autorelease)
• 千万不要放弃不属于你的对象的所有权

接下来介绍了内存管理的一些具体的方法,比如使用Accessor Methods,比如使用弱引用避免饮用循环。例如,当您向通知中心注册对象时,通知中心将存储对该对象的弱引用,并在发布相应通知时向其发送消息。当对象被释放时,您需要将其注销到通知中心,以防止通知中心将任何进一步的消息发送到不再存在的对象。同样,当一个委托对象被释放时,你需要通过向另一个对象发送一个带有nil参数的setDelegate:消息来移除委托链接。这些消息通常从对象的dealloc方法发送。

小心使用导致对象已经被销毁,Cocoa的所有权政策规定,收到的对象通常在调用方法的整个范围内保持有效。也应该可以从当前范围返回一个接收的对象,而不用担心它被释放。对于应用程序而言,对象的getter方法返回缓存的实例变量或计算值无关紧要。重要的是,该对象在您需要的时候仍然有效。

不要使用dealloc来管理稀缺资源
您通常不应该在dealloc方法中管理稀缺资源,例如文件描述符,网络连接以及缓冲区或缓存。尤其是,您不应该设计一个类,在您认为它会被调用时调用dealloc。 dealloc的调用可能由于错误或应用程序拆卸而延迟或回避。所以,避免显示调用delloc

使用auroreleasepool block

Cocoa总是希望代码在自动释放池块中执行,否则自动释放的对象不会被释放,并且您的应用程序会泄漏内存。 (如果您在自动释放池块外发送自动释放消息,Cocoa会记录一条合适的错误消息。)AppKit和UIKit框架处理自动释放池块内的每个runloop迭代(例如,向下鼠标事件或点击)。因此,您通常不必自己创建自动释放池块。但有三种情况必须使用auroreleasepool:
1,如果你写了一个不是机遇UI framework的程序,例如一个command line tool
2,如果写了个循环,循环体内创建了大量的对象,必须在loop里使用auroreleasepool,在loop结束时释放这些对象
3,你开启了一个新线程

end