文档章节

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

托楚齐坎基基
 托楚齐坎基基
发布于 2016/01/16 10:04
字数 1453
阅读 219
收藏 3

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];
     }



© 著作权归作者所有

上一篇: OC中block使用相关
下一篇: 字符串截取
托楚齐坎基基
粉丝 1
博文 16
码字总数 7868
作品 0
程序员
私信 提问
ArcGIS for iOS 开发系列(1) – 基本概念

1.1 iOS简介 2006年苹果公司发布了智能手机iPhone,卓越的外形设计和新颖的触摸式交互,令其迅速风靡全球,随后发布的平板电脑iPad同样也取得了巨大成功,二者所搭载的都是iOS智能移动操作系...

长平狐
2012/11/28
867
0
2018 iOS 面试题大全(补充完整版)

原文地址:2018 iOS 面试题大全 由于原作者并没有继续更新,这里我转过来继续更新下 这个栏目将持续更新--请iOS的小伙伴关注! 1、iOS 应用导航模式有哪些? 2、iOS 中持久化方式有哪些? 3、...

Theendisthebegi
2018/11/15
0
0
IOS软件开发视频教程要的来

IPhone开发实战视频教程内容介绍 1.iPhone开发实战视频教程-iOS开发视频教程 介绍了iPhone开发的开发环境iOS SDK,X-Code,Interface Builder,iTunes等;创建项目的基本步骤,项目工程中文件...

三毛钱
2016/07/09
242
3
理解 iOS 和 macOS 的内存管理

在 iOS 和 macOS 应用的开发中,无论是使用 Objective-C 还是使用 swift 都是通过引用计数策略来进行内存管理的,但是在日常开发中80%(这里,我瞎说的,8020 原则嘛)以上的情况,我们不需要...

Mr_zebra
2018/11/20
0
0
IOS内存常见问题与内存检查工具

iOS平台内存常见问题 作为iOS平台的开发者,是否曾经为内存问题而苦恼过?内存莫名的持续增长,程序莫名的crash,难以发现的内存泄漏,这些都是iOS平台内存相关的常见问题;本文将会详细介绍...

长平狐
2012/10/25
575
0

没有更多内容

加载失败,请刷新页面

加载更多

匈牙利命名法、骆驼命名法、帕斯卡(pascal)命名法 C#命名规范

一、匈牙利命名法:广泛应用于象Microsoft Windows这样的环境中。 Windows 编程中用到的变量(还包括宏)的命名规则匈牙利命名法,这种命名技术是由一位能干的 Microsoft 程序员查尔斯·西蒙...

南风末
9分钟前
0
0
多线程安全(synchronized、三大特性、Java内存模型)

线程安全问题? 什么是线程安全问题?简单的说,当多个线程在共享同一个变量,做读写的时候,会由于其他线程的干扰,导致数据误差,就会出现线程安全问题。 比如说,多个窗口同时卖票这个案例...

天王盖地虎626
11分钟前
1
0
jenkins备份和自动部署

jenkins备份使用的是thinbackup插件。 安装完后在系统管理里滑动到最下面有个thinbackup菜单 点击进去即可开始备份。 backup Now是备份数据。 在填完settings里面的数据后 点击即可开始备份。...

起名字什么的太麻烦了
12分钟前
0
0
RDP服务之GoldBrute僵尸网络

最近的网络攻击活动中,可能要数BlueKeep漏洞的讨论热度最高了。但近日研究人员警告称,新发现的GoldBrute僵尸网络目前对Windows系统构成了不亚于BlueKeep带来的威胁。 1. 概览 安全研究人员...

Linux就该这么学
12分钟前
0
0
好程序员web前端教程分享JavaScript验证API

好程序员web前端教程分享JavaScript验证API,小编每天会分享一下干货给大家。那么今天说道的就是web前端培训课程中的章节。 JavaScript验证API   约束验证DOM方法 PropertyDescription ch...

好程序员IT
12分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部