iphone 开发第三天 内存管理
这节要学习IOS的内存管理了,瞬间觉得要和指针不得不发生些什么故事了,好吧,淡定~~~~~
首先明确,对象的实例化需要消耗内存,要对对象分配内存。
为了防止内存泄露,就出现了垃圾回收机制,java里面也有,是程序员不需要手动管理内存分配和释放。
垃圾回收机制GC,可作为垃圾的对象就是不被任何对象参照的对象,参照就是使用的意思。
从根对象NSApplication开始追踪,需要的对象上做标记,最后将没有标记的对象当做垃圾,一次性回收。
垃圾回收虽然方便,但是影响性能,在回收过程中,必须停止应用程序的运行,而且过程较费时。
在非常重视性能的情况下,放弃GC,手动管理内存吧,iphone开发最好手动管理内存。
新概念:参照统计
默认情况下。GC被设为无效
使参照有效的方法在project settings里设置,解除对象的参照,即给赋值nil
参照统计:对某一对象来说,需要的时候,需要的人给其做一个记号,。当不需要时,再将记号去掉。任何人都不需要时,就将其释放,
管理参照次数的处理,就是参照统计。
参照统计的两个基本操作:参照对象和解除参照,retain和release,被定义在NSObject
-(id)retain 参照统计值加1,返回自己
-(void)release,解除本对象的参照,参照统计值减1,如果参照统计值变为0,则释放本对象。
retain 经常用于实例化对象
对象的生命循环就由以上两种函数来构成
类的实例化
方法是alloc,是类方法,就是前面是+号的 NSObject +(id)alloc 返回值为实例对象
使用alloc 进行实例化后,紧接着必须进行实例的 初始化 ,最基本的方法就是init方法(相当于默认的构造函数吧)
不需要特别的初始化方法时就用init函数 +(id)init
MyObject* ob;
ob = [[MyObject alloc] init];
类似 [[ClassName alloc] init] 是实例化 的基本语法之一,类似于new,初始化之后,ob参照统计值就变成1了,没用调用release之前是不能被释放的。
自动调用release:autorelease NSObject +(id)autorelease
MyObject* ob;
ob = [[[MyObject alloc ] init] autorelease];这个三段式调用语法,也是实例化的基本语法之一。
在实例化时,到底是否调用autorelease方法,取决于这个对象到底是否属于临时使用的情况。
NSString* str1;
str1 = [NSString stringWithCString:"new string"
encoding:NSACIIStringEncoding];
NSString* str2;
str2 = [[[NSString alloc] initWithCString:"new string"
encoding:NSACIIStringEncoding] autorelease];
str1只调用了一次方法就能自动释放,而str2调用了3次:alloc init autorelease
实例的释放
在释放之前需要调用dealloc:NSObject -(void)dealloc,在实例释放前调用,
在子类中重写上述方法,可以在释放前进行必要的处理,主要工作还是释放实例变量。如果类中保存了其他实例变量,必须将其释放,否则就内存侧漏了。
例如:AppController类中存在一个document的实例,那么这个dealloc方法可以这样写:
-(void)dealloc
{
[document release];
[super dealloc];
}
super 是代表父类的关键字,和java有点儿相似
内存管理的规则
临时变量,自动释放是由NSAutoreleasePool 类 实现的,定时垃圾袋;
进行自动释放时,首先创建NSAutoreleasePool的实例,类实例,随后调用自动释放对象实例的autorelease方法,将这个实例注册到NSAutoreleasePool中,
最后释放NSAutoreleasePool时,调用注册的所有对象的release方法。
NSAutoreleasePool的创建与释放时机,“事件循环机制”,较深。。。
内存管理经验总结
判断对象是长期的还是暂时的;
长期保持的,增加参照统计值
自动释放临时对象
通过dealloc减少所有的参照统计值
当然以上经验并不能概况全部,还需自己去实践才能正真理解和运用~~~~~