一:使用NSMutableArray实例时的三个内存管理要点
1.对象加入NSMutableArray实例时,对象会收到retain消息;数组对象会成为该对象的拥有方,并得到一个指向该对象的指针。
2.对象从NSMutableArray实例移出时,会收到release消息;数组对象会放弃该对象的所有权,并失去指向该对象的指针。
3.释放NSMutableArray对象时,其下所有对象都会收到release消息。
二:Retain计数规则
1. 如果开发中用来创建对象的方法,其方法名是以alloc或new开头的,或是包含copy(例如 alloc ,copy和mutableCopy方法),那么我们的类实例就已经得到了该对象的所有权。于是我们需要负责在不需要该对象的时候将其释放。这就是一种责任制的方式,谁拥有所有权,谁释放。
2.对于任何通过其他方式创建的对象,我们的类实例时没有所有权的。可以这样认为新对象的retain计数是1,而且该对象已经在NSAutoReleasePool对象中。如果没有保留该对象,那么当NSAutoReleasePool对象对drain后,对象就会被释放。
3.如果我们的类实例不拥有某个对象,但是要确保该对象继续存在,那么就需要通过向其发送retain消息来获取所有权。(这会使此对象的retain计数+1)。
4.当我们的类实例拥有某个对象并且不在需要该对象的时候,可以向其发送release消息或是autorelease消息。release消息会使retain计数立即 -1 ,autorelease会在AutoReleasePool对象被drain时,再向池中的对象发送release消息。
5.只要对象还有至少一个拥有方,该对象就会一直存在下去。知道对象的retain计数为0后,就会收到dealloc消息。才会销毁掉。
6.释放对象的同时,释放其下所有的实例变量是释放内存和避免内存泄露的重要环节。
7.ios的委托机制中,如果从mvc的设计模式角度看,委托对象通常都是控制器对象。类实例时不会保留它的委托对象。委托机制下,如果委托对象和类实例相互拥有,会产生
retain循环。简单的说,retain循环是因为两个对象相互保留,导致两者都永远无法释放。要避免retain循环,需要将delegate属性设置为assign特性,而不是copy或reatin。对象的指针成员变量指向另外一个对象,但是不保留该对象。这种情况成为weak reference。
@property (nonatomic ,assign) id delegate;
拥有对象可以确保该对象的存在,避免像不存在的对象发送消息。所以,当对象不能保留它的委托对象时,委托对象必须负责在释放自己的时候通知相应的对象。
三. UIViewController
和其它对象一样,视图控制对象也是通过alloc和init创建的。但是视图控制对象不会在创建的那一刻马上创建相应的视图,而是要等到真正的需要试图时,才会通过调用loadView来创建。这种延迟创建的做法能提高内存的使用效率。例如:如果某个标签条有很多UIViewController对象,那么任何一个UIViewController对象的视图,只会在相应的标签项被选中时才会被创建出来。视图控制对象会在收到view消息的那一刻载入视图。 在UIViewController的初始化方法里访问实例变量view,会导致延迟载入机制失效。这个问题看似不严重,但如果考虑内存过低警告的因素,问题就大了。
所以,可以定出以下规则:不要在视图控制对象的初始化方法中访问该对象的视图。如果知道你对视图有额外的工作需要完成,可以在ViewDiDLoad中实现。
四:内存过低警告
当系统的可用内存过低时,系统会向当前运行的应用发出内存过过低警告。收到该消息的应用需要做一下回应:在收到消息的那一刻,释放所有不需要使用的,有易于重建的资源。视图控制对象会在发出内存过低警告是收到didReceiveMemoryWarning消息。didReceiveMemoryWarning方法的默认实现:
检查视图控制对象的视图是否可见,如果不可见就释放掉(如果可见就什么也不做);
iOS开发中理解内存的管理技巧应该从局部的角度考虑问题。只关心类内部对对象的使用,以类为分界考虑内存管理问题。
此内容来自 iso编程 读书笔记。