iPhone内存管理详细解说(一)

article/2025/4/20 7:29:53

iPhone内存管理详细解说系列转载来源:http://keywind.me/blog/2011/05/07/iphonenei-cun-guan-li-xiang-xi-jie-shuo-yi/ 感谢这位作者


做iPhone开发内存管理是避免不了的问题,而且Apple不对iOS进行垃圾回收机制肯定有他的原因.要想清楚了解内存管理,官方文档是最好的资源,于是把这几天看的Memory Management Programming Guide进行整理,一方面做记录,一方面供大家做参考,一些地方翻译的不好还请留言指出.

一:介绍

相对于Mac OS X v10.5+,iOS不支持垃圾回收机制; 相对于普通系统复杂的内存管理,cocoa定义了一些规则来使其变得简单.

二:内存管理规则

基本规则为: 你只能release或autorelease你拥有的object.这句话可具体为:

  • 如果你调用一个方法,这个方法以alloc,new或copy开头;或者你发送一个retain消息,你就拥有这个object.
  • 你可以使用release或者autorelease来放弃一个object的拥有权.

以下两条规则从上面那条延伸而来:

  • 如果你想保存一个接收到的object作为你的实例变量的属性,你必须retain或copy它,通常你使用accessor方法来简化这一步
  • 为了保证接收到的object在它被接收的方法内保持有效,并且安全地返回给这个方法的调用者,你可以使用retain和release或autorelease组合实现

三:object的拥有和丢弃

1.object的所有权政策

一个object可以有一个或更多的拥有者,只要这个object还有至少一个拥有者,它就不被销毁.Cocoa设定以下四条规则:

  • 你拥有你创建的object,使用alloc,new或copy创建
  • 你可以使用retain拥有一个object,来保证你还需要它存在
  • 你必须放弃你不再需要的objects的所有权,使用release或autorelease
  • 你不能尝试放弃你并没有所有权的object

例子:

{Thingamajig *myThingamajig = [[Thingamajig alloc] init];// ...NSArray *sprockets = [myThingamajig sprockets];// ...[myThingamajig release];
}

你用alloc创建myThingamejig,所以要用release释放,而sprockets并不是你创建的,所以不必释放.

2.内幕:retain counts

所有权政策的底层实现靠的是retain counts,每个object都有retain count. 创建一个object,retain count=1; retain这个object,retain count+1; release这个object,retain count-1; autorelease这个object,retain count在未来某个时候-1; 要注意的是,不要可以去查看retainCount的值来判断是否释放,只会误导你,没有意义.

3.Autorelease

Autorelease有Autorelease Pools实现,看例子:

– (NSArray *)sprockets {NSArray *array = [[NSArray alloc] initWithObjects:mainSprocket,auxiliarySprocket, nil];return [array autorelease];
}

这个是正确的写法,你alloc了array,但由于你要返回array给这个方法的调用者,所以不能马上释放,又不能不释放,所以有延迟的autorelease就成了最佳选择.而如果:

– (NSArray *)sprockets {NSArray *array = [[NSArray alloc] initWithObjects:mainSprocket,auxiliarySprocket, nil];return array;
}

由于array是局部变量,这样你就释放不掉它了.再看:

– (NSArray *)sprockets {NSArray *array = [[NSArray alloc] initWithObjects:mainSprocket,auxiliarySprocket, nil];[array release];return array; // array is invalid here
}

由于array已经被释放了,所以也就不能返回给这个方法的调用者了,再看:

– (NSArray *)sprockets {NSArray *array = [NSArray arrayWithObjects:mainSprocket,auxiliarySprocket, nil];return array;
}

你没有所有权,所以不要你释放.

4.共享的objects的有效性

共享的objects既要保证在调用的函数被保持有效,也要保证该函数在把objects return出去的时候因为release而变得无效了.简而言之就是保持objects在你需要的时候保持有效. 要注意两种意外:

(1)当一个object是从集合类(NAArray,NADictionary等等)中移除的:

heisenObject = [array objectAtIndex:n];
[array removeObjectAtIndex:n];
// heisenObject could now be invalid.

当一个object是从集合类中移除的,它就被发送一个release,如果集合类是它唯一的拥有者,那么这个object就被释放了.

(2)当一个object的父object被释放:

id parent = <#create a parent object#>;
// ...
heisenObject = [parent child] ;
[parent release]; // Or, for example: self.parent = nil;
// heisenObject could now be invalid.

当你从object1派生出object2,然后把object1释放,如果object1是object2唯一的拥有者,那么object2也将被释放 为了防止以上两种情况发生,你可以retain一下使拥有拥有权,然后不再需要时释放,比如

heisenObject = [[array objectAtIndex:n] retain];
[array removeObjectAtIndex:n];
// use heisenObject.
[heisenObject release];
5.Accessor(存取器)方法

如果你的类的有一个实例变量是一个object,你需要保证这个object的任何属性在你这个使用这个object时没有被释放.因此需要声明拥有权. 比如你的object允许它的MainSprocket属性被设置,你可以这样实现:

– (void)setMainSprocket:(Sprocket *)newSprocket {[mainSprocket autorelease];mainSprocket = [newSprocket retain]; /* Claim the new Sprocket. */return;
}

需要把之前的mainSprocket先释放,值得注意的是,如果object1调用setMainSprocket,参数是object2的MainSprocket,也就是两者现在共享一个MainSprocket,此时如果object2的MainSprocket改变,object1的也跟着改变.如果你不想这样,你可以:

– (void)setMainSprocket:(Sprocket *)newSprocket {[mainSprocket autorelease];mainSprocket = [newSprocket copy]; /* Make a private copy. */return;
}

这还有个问题,由于以上两个方法都是把原先的MainSprocket给autorelease了,但如果前后两个sprocket是一样的,当这个sprocket被release了那么你再retain或者copy就错了,这时你可以:

– (void)setMainSprocket:(Sprocket *)newSprocket {if (mainSprocket != newSprocket) {[mainSprocket release];mainSprocket = [newSprocket retain]; /* Or copy, if appropriate. */}
}
6.释放object

当一个object的retain count等于0时,它的dealloc方法被调用,用来释放它占有的内存,和其他资源,包括其他实例变量或者说object的拥有权,比如以下的实现释放了mainSprocket和auxiliarySprocket的所有权:

- (void)dealloc {[mainSprocket release];[auxiliarySprocket release];[super dealloc];
}
7.引用的objects

一些方法指定一个object是以引用形式被返回的,(如ClassName * 或 id ),举一些例子:

 initWithContentsOfURL:options:error: (NSData)initWithContentsOfFile:encoding:error: (NSString)executeFetchRequest:error: (NSManagedObjectContext)

这是因为你没有所有权,所以不必释放,例如:

NSString *fileName = <#Get a file name#>;
NSError *error = nil;
NSString *string = [[NSString alloc] initWithContentsOfFile:fileNameencoding:NSUTF8StringEncoding error:&error];
if (string == nil) {// deal with error ...
}
// ...
[string release];
8.retain循环现象

先看图:

image

以上现象中Document创建一个Page,Page追踪它在哪个Document,如果Document去retain它的Page,而Page也去retain它所在的Document,那么我们知道两者成循环永远释放不掉. 此时解决办法是Document去retain它的page,而Page引用它所在的Document,这被称为”弱引用”.

9.弱引用

可以简单理解为强引用是拥有所有权,而弱引用没有.一些Cocoa典型的弱引用包括:table data sources, outline view items, notification observers, miscellaneous targets 和 delegates. 比如:NSTableView的object不会去retain它的data source,NSApplication不会去retain它的delegate. 你需要注意的是,发送消息给一个你只持有弱引用且已被销毁的object会使程序崩溃,一般条件下被弱引用的object在被销毁时需要通知弱引用的持有者,比如:当你在notification center注册一个object,notification center就持有这个object的弱引用以便notification到来时给它发送消息.此时如果这个object被销毁了,你就要在notification center注销以防止notification center给不存在的object发送消息.


http://chatgpt.dhexx.cn/article/kYo69XJO.shtml

相关文章

​iPhone内存满了,变成白苹果了,怎么解决?

iPhone内存不足导致我们手机变成白苹果&#xff0c;开机之后还是白苹果&#xff0c;如何解决问题&#xff1f;分享几个方法给大家&#xff1a; 重启 iPhone强制重启&#xff0c;也许能帮我们退出暂时的白苹果界面。手机各型号强制重启的方法如下&#xff1a; 强制重新启动 i…

怎么清理iPhone12中内存里的“其他”

你手机的空间占用和下图类似吗? 打开「iPhone存储空间」选项&#xff0c;会发现占据空间最多的往往不是「微信」、不是「照片」&#xff0c;而是神秘的「其他」。根据苹果的描述&#xff0c;「其他」包括「缓存、日志和系统当前使用的其他资源。此数值将随着系统要求浮动」&am…

iPhone如何查看剩余内存容量 从哪里能看

如今现在的很多主流手机都没有了SD卡拓展功能&#xff0c;这在iPhone很久以前就取消了&#xff0c;对于一些经常使用但不了解内存的朋友;来说&#xff0c;如何查看内存使用情况是个问题&#xff0c;那么&#xff0c;iPhone如何查看剩余内存容量? 从哪里能看?以前来看看吧。 …

iPhone 手机内存,

iPhone,iPhone 3G:128MB内存&#xff0c; iPhone 3GS和iPad:256MB内存。 iPhone 4&#xff08;4s&#xff09;&#xff1a;512MB内存&#xff0c;800MHZ, iPhone5s :1G内存 16Gb,的存储 网络模式&#xff1a;HSPA&#xff0c;联通3G&#xff08;WCDMA&#xff09;&#xff0c;联…

iphone开发--内存管理

内存管理是iphone开发中很重要的一个环节&#xff0c;没有处理好会是系统出现很多问题&#xff0c; 很严重的一个就是直接导致程序闪退。因此&#xff0c;内存管理是很让新手头疼的&#xff0c;也是新手晋 级为菜鸟必走的一个环节。今天讨论的主题就是内存管理。 内存管理包括…

开源超融合私有云神器proxmox VE

Prxomox VE由位于奥地利维也纳的Proxmox Server Solutions GmbH开发&#xff0c;这让人有点意外。其实欧洲在IT技术方面&#xff0c;还是很强的&#xff0c;比如大名鼎鼎的mysql&#xff0c;出自瑞典&#xff1b;分布式文件系统moosefs&#xff0c;出自波兰。Proxmox主打产品有…

超融合基础架构

以软件为中心&#xff0c;替代传统架构 超融合基础架构是一种融合的、统一的 IT 基础架构&#xff0c;它包含了传统数据中心常见的元素: 计算、存储、网络以及管理工具。超融合基础架构解决方案是以软件为中心&#xff0c;结合 x86 或 ARM 架构的硬件替代传统架构中昂贵的专用硬…

VSAN超融合笔记

VMware VSAN VMware vSAN是一款软件定义的企业存储解决方案&#xff0c;支持超融合基础架构&#xff08;Hyper-Converged Infrastructure,HCI&#xff09;系统。VSAN使用软件定义的方法为虚拟机创建共享存储。可以虚拟化ESXI主机的本地物理存储资源&#xff0c;并将这些资源转…

浅谈——服务器虚拟化超融合存储

目录 一、服务器虚拟化&#xff1a; 二、服务器虚拟化技术优点&#xff1a; 三、基于虚拟服务器的双机热备&#xff08;VM漂移技术&#xff09; 四、服务器的超融合技术 五、服务器的存储&#xff1a; ①FC存储&#xff1a; ②FCOE技术存储 ③iSCSI存储 六.服务的分类: 一…

超融合和虚拟化区别-学习笔记

前沿,传统数据中心的特点。 传统的数据中心可以归为三层架构(虚拟化、服务器)、网络设备、存储设备。主要缺点为: ① 性能方面:程序放在SERVERS上,与这些程序相关的数据存在SAN,NETWORKING(IP/FC网络)成为瓶颈。 ② 可扩展方面:扩展业务,不能在此架构下淘汰更换SAN…

超融合相关知识整理

一、基本概念 HCI是一种横向扩展&#xff0c;软件集成的基础架构&#xff0c;它采用模块化方法来计算&#xff0c;网络和存储容量。HCI没有使用专用硬件&#xff0c;而是利用了分布式&#xff0c;水平的商品硬件块&#xff0c;并提供了一个用于报告和管理的单窗格仪表板。外形…

虚拟化、云计算与超融合的简单总结

一、概述 近期研究了一下超融合的内容&#xff0c;简单做了下学习总结。 虚拟化是一种基本思想&#xff0c;是云计算、超融合的基础&#xff0c;在信息系统的各层都有不同的应用&#xff0c;举例来说&#xff1a; 存储虚拟化&#xff0c;存储阵列就是将若干集中部署的磁盘先汇总…

超融合之VMware vSAN企业级超融合解决方案

一、什么是VMware vSAN&#xff1f; 软件定义的存储&#xff08;vSAN&#xff09;是软件定义的数据中心的基本组件&#xff0c;可对存储资源进行抽象化处理&#xff0c;以支持存储的池化、复制和按需分发。这使存储层与虚拟化计算层非常相似&#xff1a;都具有聚合、灵活、高效…

深信服超融合技术架构(重点介绍主要模块)

目录 超融合架构定义系统总体架构 1.aSV 计算机虚拟化平台1.1 概述1.2 aSV 技术原理1.2.1 Hypervisor 分类(1)裸金属型(2)宿主型(3) aSV 的 Hypervisor 实现 1.3 aSV 技术特性1.3.1 内存 NUMA 技术1.3.2 SR-IOV1.3.3 Faik-raid1.3.4 虚拟机生命周期管理1.3.5 虚拟机热迁移 1.4 …

微软超融合+混合云:源自Azure技术的超融合架构

--------------------------------------------------------------------------------------------------------- 2021年5月更新&#xff1a; Azure Stack HCI 2021年5月10日正式落地Azure世纪互联&#xff0c;中国Azure的用户可以更简单的在本地的数据中心建立微软混合云&am…

转:什么是超融合?超融合有什么作用,超融合的概念.

中国人非常喜欢这个“融”字&#xff0c;IDC数据显示&#xff0c;2015年中国超融合市场整体规模达到9170万美元&#xff0c;超过2014规模的3倍&#xff0c;在Gartner 2016年7月公布的技术成熟度曲线中&#xff0c;超融合位于期望膨胀期的最顶点&#xff0c;这预示着&#xff0c…

超融合

在云架构中&#xff0c;首先要了解“融合”是什么含义&#xff1f;融合就是将两个或多个组件组合到一个单元中&#xff0c;组件可以是硬件或软件。就虚拟化和私有云而言&#xff0c;按照是否完全以虚拟化为中心&#xff0c;融合分为物理融合和超融合两种。 超融合是融合的一个…

2021-7-14-超融合基础知识

超融合基础知识 内容参考&#xff1a; Mars小歪&#xff0c;四海骄阳&#xff0c;钱曙光 1&#xff0c;什么是超融合 既然在说超融合架构&#xff0c;那就肯定有一般的融合架构&#xff0c;这其实也是目前行业内对于超融合定义争论的焦点&#xff0c;也就是说哪些定义为融合…

超融合及其意义

前言 当下超融合是个热门的词&#xff0c;那么超融合融合了什么&#xff1f;为什么要搞超融合&#xff1f;超融合架构如何搭建&#xff1f;了解超融合对个人和企业分别有何意义&#xff1f;本文将阐述作者自己的理解和看法。 IT基础架构演进与超融合 从IT基础架构的演进可以…

HX/VSAN超融合技术学习笔记

几种不同的基础架构 1.独立机架式服务器 资源无法灵活的扩容和更换 2.serverSAN存储架构 计算资源无法灵活的扩容和更换 存储池化&#xff0c;但是计算资源、内存还是无法灵活更换 3.ServerSAN存储架构应用群集 同个应用运行在多个server上&#xff0c;可灵活调整使用的计算…