IOS有关内存管理的二三事

IOS有关内存管理的二三事

一、前引

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

二、Xcode工程设置ARC

ARC是xcode5中引入的自动引用计数,其原理与MRC是一样,只是系统帮助我们添加了retain和release。现在在xcode中新建的项目默认都是ARC的环境,我们可以通过设置其为MRC。

在BuildSettings中搜索ARC:

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

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

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

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

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

如果工程是ARC,要混编MRC的文件,我们选中compiler flags,后面设置为-fno-objc-arc

如果工程是MRC,要混编ARC文件,我们在后面设置-fobjc-arc

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

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

首先,在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,如此一来,对象内存便被统一的管理了起来。

五、内存管理的黄金法则

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

黄金法则:

1、当你使用alloc,new,copy,mutableCopy创建对象时,你才需要管理他们。

2、你可以使用retain给一个对象增加引用计数。

3、当你不再需要一个对象时,你必须调用release减少其引用计数。

4、你不能释放不属于你的对象的所有权。

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

六、自动释放池

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

1、MRC时:

?


1

2

3

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc]init];//创建一个自动释放池,系统默认会为我们创建一个,我们也可以创建自己的。

    UIImage * image = [[[UIImage alloc]init] autorelease];//在池内创建一些对象,会和最近的自动释放池匹配

    [pool release];//这时自动释放池会向池子中的每一个对象发送release消息

2、ARC时:

?


1

2

3

  @autoreleasepool {

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

    }


时间: 2024-10-29 12:16:27

IOS有关内存管理的二三事的相关文章

理解iOS的内存管理

远古时代的故事 那些经历过手工管理内存(MRC)时代的人们,一定对 iOS 开发中的内存管理记忆犹新.那个时候大约是 2010 年,国内 iOS 开发刚刚兴起,tinyfool 大叔的大名已经如雷贯耳,而我还是一个默默无闻的刚毕业的小子.那个时候的 iOS 开发过程是这样的: 我们先写好一段 iOS 的代码,然后屏住呼吸,开始运行它,不出所料,它崩溃了.在 MRC 时代,即使是最牛逼的 iOS 开发者,也不能保证一次性就写出完美的内存管理代码.于是,我们开始一步一步调试,试着打印出每个怀疑对象的

深入SQL SERVER 2000的内存管理机制(二)

server 深入SQL SERVER 2000的内存管理机制(二)     http://msdn.microsoft.com/data/default.aspx?pull=/library/en-us/dnsqldev/html/sqldev_01262004.asp   可访问大地址的应用 (Large-Address-Aware Executables) 在Windows增加支持/3GB参数以前,一个应用程序是无法访问一个带有高位设置的指针.一个32位的指针只有前31位地址空间可以被用户

IOS中内存管理那些事_IOS

Objective-C 和 Swift 语言的内存管理方式都是基于引用计数「Reference Counting」的,引用计数是一个简单而有效管理对象生命周期的方式.引用计数分为手动引用计数「ARC: AutomaticReference Counting」和自动引用计数「MRC: Manual Reference Counting」,现在都是用 ARC 了,但是我们还是很有必要了解 MRC. 1. 引用计数的原理是什么? 当我们创建一个新对象时,他的引用计数为1: 当有一个新的指针指向这个对象

iOS ARC 内存管理要点

前言 在讨论 ARC 之前,我们需要知道 Objective-C 采用的是引用计数式的内存管理方式,这一方式的特点是: 自己生成的对象自己持有.比如:NSObject * __strong object = [NSObject alloc] init];. 非自己生成的对象自己也能持有.比如:NSMutableArray * __strong array = [NSMutableArray array];. 自己持有的对象不再需要时释放. 非自己持有的对象自己无法释放. 而 ARC 则是帮助我们

iOS - OC 内存管理

1.OC 基本内存管理模型 1.1 自动垃圾收集 在 OC 2.0 中,有一种称为垃圾收集的内存管理形式.通过垃圾收集,系统能够自动监测对象是否拥有其他的对象,当程序执行需要空间的时候,不再被引用的对象会自动释放.iOS 运行环境并不支持垃圾收集,在这个平台开发程序时并没有这方面的选项.在 OS X 10.8 中垃圾收集已不再推荐使用. 1.2 自动释放池 自动释放池(autoreleasepool)的机制是它使得应用在创建新对象时,系统能够有效的管理应用所使用的内存.自动释放池可以追踪需要延时

Symbian内存管理的二十二条军规

1.C类必须有析构函数,这是CBase的一个虚函数. 2.C类的构造函数和ConstructL()必须为protect或private类型的成员函数3.在C class中必须有一个NewLC()函数,除非它是嵌套类.NewL()是可选的,并且总是根据NewLC()来实现. 4.NewL()和NewLC()在c class中必须是static函数. 5.C类通过指针和引用来传递. 6.拷贝构造函数在symbian中没有用. 7.不一定要在析构函数中删除类的成员对象.(生命期结束即可删除) 8.析构

iOS/OS X 内存管理(二):借助工具解决内存问题

上一篇博客iOS/OS X内存管理(一):基本概念与原理主要讲了iOS/OSX 内存管理中引用计数和内存管理规则,以及引入ARC新的内存管理机制之后如何选择ownership qualifiers(__strong.__weak.__unsafe_unretained和__autoreleasing)来管理内存.这篇我们主要关注在实际开发中会遇到哪些内存管理问题,以及如何使用工具来调试和解决. 在往下看之前请下载实例MemoryProblems,我们将以这个工程展开如何检查和解决内存问题. 悬挂

操作系统概念学习笔记 16 内存管理(二) 段页

操作系统概念学习笔记 16 内存管理 (二) 分页(paging) 分页(paging)内存管理方案允许进程的物理地址空间可以使非连续的.分页避免了将不同大小的内存块匹配到交换空间上(前面叙述的内存管理方案都有这个问题,当位于内存中的代码和数据需要换出时,必须现在备份存储上找到空间,这是问题就产生了.备份存储也有前面所述的与内存相关的碎片问题,只不过访问更慢). 传统上,分页支持一直是由硬件来处理的.最近的设计是通过将硬件和操作系统相配合来实现分页. 基本方法 实现分页的基本方法设计将物理内存分

iOS 进阶—— iOS内存管理

1 似乎每个人在学习 iOS 过程中都考虑过的问题 alloc retain release delloc 做了什么? autoreleasepool 是怎样实现的? __unsafe_unretained 是什么? Block 是怎样实现的 什么时候会引起循环引用,什么时候不会引起循环引用? 所以我将在本篇博文中详细的从 ARC 解释到 iOS 的内存管理,以及 Block 相关的原理.源码. 2 从 ARC 说起 说 iOS 的内存管理,就不得不从 ARC(Automatic Referen