iOS开发中的内存管理机制浅谈

iOS开发中的有关内存管理

1、前引

随着移动设备的内存愈来愈大,程序员也已经度过了为了那一两M的内存在系统的抽丝剥茧的年代,对于JAVA的开发者,对内存更是伸手即取,而且从不关心何时还回去。可是,程序的掌控度对程序员来讲是相当重要的,任何语言的内存管理机制的初衷也是在有限的空间里完成最精致的逻辑。程序员

2、Xcode工程设置ARC

ARC是xcode5中引入的自动引用计数,其原理与MRC是同样,只是系统帮助咱们添加了retain和release。如今在xcode中新建的项目默认都是ARC的环境,咱们能够经过设置其为MRC。xcode

在BuildSettings中搜索ARC:安全


将下面的参数设置为NO,默认是YES。app


这时项目工程的环境就变成了MRC。ui

3、项目中实现MRC和ARC混编

现实中的许多旧的项目,还有一些比较老的第三方库,可能都是采用MRC环境编写的,咱们在对其进行扩展或者作新项目的兼容的时候,能够在xcode中对其进行混编。spa

选择:target->build phases->compile sources.net


若是工程是ARC,要混编MRC的文件,咱们选中compiler flags,后面设置为-fno-objc-arc指针

若是工程是MRC,要混编ARC文件,咱们在后面设置-fobjc-arccode

4、IOS内存管理机制基本原理

不管你是只注重于代码逻辑,将内存交给ARC的新时代程序员,仍是依然对apple的信任不足,依然事必躬亲的MRC古板程序员,我想你都应该了解IOS中内存管理的机制,尽管ARC机制很成熟也很可靠,但是依然会有不少应用存在循环应用,内存泄露等问题,要知道,ARC不是万能的,它仅仅只是帮你省去写一些繁琐的代码。orm

首先,在Object-C中建立对象返回的并非对象自己,而是一个指针。好比咱们使用alloc申请空间,会常常这样作:

UIImage * image = [[UIImage alloc]init];

这里,调用的alloc时,系统将给咱们建立的类分配一块内存空间,并返回一个指向这个空间的指针。调用init时对对象进行初始化。若是此时,咱们将image这个指针置为nil:image=nil;那样将形成内存泄露,系统分配给image的空间永远没法回收。因此,在咱们不须要image这个对象时,咱们会使用dealloc方法将其交还给系统:[image dealloc];然而这里,有将产生一个严重的问题,若是咱们此时打印image的指针,会发现它如今成了一个危险东西,由于它指向的东西不存在了,而它却依然指向那个地方,这即是不少程序员的噩梦:野指针。为此,咱们应该养成一个好习惯,不用的指针置为nil,全部对空指针进行的操做都被认为是安全的。

经过上面的理解,咱们发现了一个很是麻烦的地方,我申请了一块内存空间,若是我将指针置空了而没有释放对象,则会内存泄露,若是我提早释放了对象,又极可能会有野指针的出现。而且若是有不少类都引用了这个对象,我甚至的不知道我应该何时释放它。所以,Object-C为咱们引入了引用计数这种管理内存的方法,任何引用这个对象的地方,都应该让这个对象的引用计数加1。一样,任何再也不须要这个对象的地方,也应该使它的引用计数减1,如此一来,对象内存便被统一的管理了起来。

5、内存管理的黄金法则

引用计数内存管理的机制是对象的计数,每一个对象至少会有一个引用者,若是没有了引用者,对象会被释放。

黄金法则:

一、当你使用alloc,new,copy,mutableCopy建立对象时,你才须要管理他们。

二、你可使用retain给一个对象增长引用计数。

三、当你再也不须要一个对象时,你必须调用release减小其引用计数。

四、你不能释放不属于你的对象的全部权。

上面就是黄金法则的全部内容,我译的可能不到位,总结为一点,也是相当重要的一点就是:谁建立了对象,谁释放掉对象。谁增长了引用计数,谁就在不用时减小计数。alloc,new,copy,mutableCopy,retain这些方法会使引用计数增长,release会使引用计数减小,当计数为0时,系统会调用dealloc释放内存。

6、自动释放池

为了方便内存管理,避免咱们频繁的调用release方法,Object-C中还为咱们引用了一种机制:自动释放池。自动释放池的原理其实只是延时释放,它并无帮咱们作太多的工做。自动释放池的使用方式有两种:

一、MRC时:

?

1
2
3
     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc]init]; //建立一个自动释放池,系统默认会为咱们建立一个,咱们也能够建立本身的。
     UIImage * image = [[[UIImage alloc]init] autorelease]; //在池内建立一些对象,会和最近的自动释放池匹配
     [pool release]; //这时自动释放池会向池子中的每个对象发送release消息

二、ARC时:

?

1
2
3
   @autoreleasepool {
         UIImage * image = [[[UIImage alloc]init] autorelease];
     }
相关文章
相关标签/搜索