iOS 内存管理
一 . 内存管理 包括内存分配 和 内存清除
1.内存管理的范围 :人和继承于NSObject类的对象都需要进行内存管理,任何非对象类型的对象(基本数据类型 如 int char float double struct enum等)
2.为什么只有OC对象才需要进行内存管理?
OC对象放在堆里面 非OC对象(基本数据类型 如 int char float double struct enum等)一般放在栈里面,栈内存会被系统自动回收
3.堆和栈
栈(操作系统):有系统自动分配释放,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈(先进后出)
堆(操作系统):一般由程序员手动分配释放,如果程序员不释放,程序结束时就会被系统回收,分配方式类似于链表
4.引用计数器
每个OC对象都有自己的引用计数器 从字面上可以理解成”对象被引用的次数” 也可以理解为有多伤风人正在使用这个对象
引用计数器的作用:引用计数器表示当前有多少人正在使用这个对象 到没有任何人在使用这个对象时系统就会回收这个对象 也就是说当对象的引用计数为0时,对象占用的内存就会被系统回收.如果系统的引用计数不为0那么在整个程序运行过程中,他占用的内存就不可能被回收(除非整个程序以经推出)
任何一个对象在刚创建的使用引用计数都为1 当使用 alloc init copy 等创建对象时,对象的引用计数默认为1
5.如何操作引用计数器
给对象发送一个 retain 消息 可以使引用计数器的值 +1
给对象发送一个 release 消息 可以使引用计数器的值 -1 ,release 并不代表销毁\回收对象 仅仅是引用计数值 -1
给一二对象发送 retainCount 消息 可以得到当前对象的引用计数器值 有时候不准确 很少用 因为常出错
需要注意的是: release 并不代表销毁\回收对象 仅仅是引用计数值 -1 只有当引用计数器值减到0 就会释放
6.dealloc方法
当一个对象的引用计数器为0时,这个对象即将被释放,其占用的内存被系统回收
对象即将被销毁时系统会自动给对象发送一条dealloc消息(因此,从dealloc方法有没有被调用.就可以判断对象是否被销毁)
dealloc函数是系统调用的函数.不可程序员直接调用.一般情况下,会重写dealloc方法来释放相关资源,重写的dealloc方法就相当于对象的遗言,用来处理对象销毁后的一些后事.一旦重写了dealloc方法,就必须调用 [super dealloc] 并且放在dealloc方法的最后调用.
注意事项:dealloc方法是系统调用的方法,程序员不可直接调用,需要重写dealloc方法.一旦对象被回收,它占用的内存就不可再用,如果坚持使用就会导致程序崩溃(野指针错误)
二 .MRC(Manual Reference Counting) :所有的对象需要程序员手动管理,需要程序员自己编写release/retain等方法
1.内存管理的原则 :有加就有减 一次alloc就有一次release 一次retain就有一次release
2.野指针 空指针 僵尸对象
僵尸对象 : 只要一个对象引用计数为0 被释放 就称这个对象为僵尸对象
野指针 : 当一个对象指向僵尸对象,我们就成这个指针为野指针 (一个指针指向的对象的引用计数值为0 则这个指针为野指针).只要给野指针发送消息就会报错 EXC_BAD_ACCESS
企业开发中 一定要开启对僵尸对象的监听
空指针 : 为了避免给野指针放消息会报错,当一个对象被释放后我们会将这个对象设置成空指针nil/0. 因为给空指针发送消息不会报错.
3.多对象的内存管理
如果要在A对象和B对象中用C对象 一定要在A对象和B对象中对C对象进行一次retain 当A和B用完后也要对C进行release 一般情况下,A和B对C的retain放在A和B对C的调用函数中,A和B对C的release放在dealloc方法中.其余的A B C 的自释放都在原来的主函数中.
就像好几个人进一个游戏大厅打游戏,每进去一个人都要让大厅记录+1,当有人离开时,大厅里人数就会-1.当大厅里人数纪录为0时,就大厅释放.只要还有人,哪怕是一个人也不能释放大厅.
4.@property修饰符
readonly:只生成getter方法
readwrite:同时生成getter/setter方法,默认情况下不写就是readwrite
getter:可以给生成的gutter方法起名称
setter:可以给生成的setter方法起名称
retain:会自动帮我们生成setter/gettter方法内存管理的代码
assign:不会替我们生成setter方法的内存管理方法,仅仅只是生成普通的gettter/setter方法,默认什么都不写就是assign
5.@class
@class 可以简单地引用一个类,就是告诉系统这是一个类,可以放心大胆的使用.
具体使用中,在 .h 文件中使用 @class, 在 .m 文件中使用 #import包含这个类的 .h 文件. @class 不拷贝这个类只是告诉编译器这是一个类,可以使用. #import 会拷贝累的头文件.
在用到 @class 时,在 .h 文件里 @class,同时在 .m 文件里也要 #import,不可省略.
对于循环以来的关系使用@class可以避免死循环,因为 .h 文件中的 @class 不做任何拷贝, .m 文件中的 #import 只会拷贝对应的文件,不会形成死循环.
6.循环retain
如果A对象要拥有B对象,且B对象也要拥有A对象.此时就会形成循环retain
解决办法:让其中一方不要做retain操作
7.autorelease
只要给一个对象发送autorelease消息,就会将对象放到一个自动释放池中,当自动释放池销毁时,会对池子里面的所有对象做一次release操作.
注意:这里只是发送autorelease消息,如果当时的引用计数值为0,则对象销毁,否则对象不会被释放. 调用完autorelease方法后,对象的引用计数值不会改变
autorelease的原理:autorelease实际上只是把对release的调用延迟了,对于每个autorelease系统只是把对象放到当前的自动释放池中,挡自动释放池被释放时,该吃中的所有对象都会被release
三.ARC(Automatic Reference Counting) : 不需要程序员管理内存,编译器会自动给程序议案家release/retain等代码
1.注意点
iOS中的ARC和java中的垃圾回收机制不同.iOS中的ARC是编译器在编译阶段自动识别添加release/retain等方法带代码中在执行代码;java中的垃圾回收机制是系统在运行程序是定时检测垃圾并回收,是系统做的.
2.ARC的判断原则
使用ARC时只要还有一个强指针变量指向对象,对象就会保持在内存中
强指针:被__strong修饰的指针,如果没有修饰词,默认的情况下都是强指针,强指针指向的对象会一直保存在内存中
弱指针:被__weak修饰的指针 ,弱指针指向的对象在创建完成后会立即被释放,无法保存
3.ARC中的循环引用
在ARC中如果A拥有B,B拥有A,一个用strong 一个用weak,必须有一方使用弱指针
4.ARC中@property参数
strong : 用于OC对象,相当于MRC中的retain
weak : 用于OC对象,相当于MRC中的assign
assign : 用于基本数据类型,相当于MRC中的assign
iOS 内存管理的更多相关文章
- iOS内存管理
iOS内存管理的方式是引用计数机制.分为MRC(人式引用计数)和ARC(自动引用计数). 为什么要学习内存管理? 内存管理方式是引用计数机制,通过控制对象的引用计数来实现操作对象的功能.一个对象的生命 ...
- 【Bugly干货分享】iOS内存管理:从MRC到ARC实践
Bugly 技术干货系列内容主要涉及移动开发方向,是由Bugly邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 对于iOS程序员来说,内存管理是入门的 ...
- iOS内存管理个人总结
一.变量,本质代表一段可以操作的内存,她使用方式无非就是内存符号化+数据类型 1.保存变量有三个区域: 1>静态存储区 2>stack 3>heap 2.变量又根据声明的位置有两种称 ...
- IOS内存管理学习笔记
内存管理作为iOS中非常重要的部分,每一个iOS开发者都应该深入了解iOS内存管理,最近在学习iOS中整理出了一些知识点,先从MRC开始说起. 1.当一个对象在创建之后它的引用计数器为1,当调用这个对 ...
- iOS内存管理编程指南
iOS 内存管理 目录[-] 一:基本原则 二:成员变量的内存管理 三:容器对象与内存管理 四:稀缺资源的管理 五:AutoRelease 六:其他注意事项 iOS下内存管理的基本思想就是引用计数,通 ...
- iOS内存管理(一)
最近有时间,正好把iOS相关的基础知识好好的梳理了一下,记录一下内存相关方面的知识. 在理解内存管理之前我觉得先对堆区和栈区有一定的了解是非常有必要的. 栈区:就是由编译器自动管理内存分配,释放过程的 ...
- iOS内存管理 ARC与MRC
想驾驭一门语言,首先要掌握它的内存管理特性.iOS开发经历了MRC到ARC的过程,下面就记录一下本人对iOS内存管理方面的一些理解. 说到iOS开发,肯定离不开objective-c语言(以下简称OC ...
- 75.iOS内存管理
堆区和栈区 1.栈区:由编译器自动分配释放,函数的参数值,局部变量等值 2.堆区:一般由开发人员分配释放,若不释放,则可能会引起内存泄漏 NSString *string = @"abcd& ...
- iOS 内存管理-copy、 retain、 assign 、readonly 、 readwrite、nonatomic、@property、@synthesize、@dynamic、IB_DESIGNABLE 、 IBInspectable、IBOutletCollection
浅谈iOS内存管理机制 alloc,retain,copy,release,autorelease 1)使用@property配合@synthesize可以让编译器自动实现getter/setter方 ...
- iOS内存管理策略和实践
转:http://www.cocoachina.com/applenews/devnews/2013/1126/7418.html 内存管理策略(memory Management Policy) N ...
随机推荐
- Android动态加载框架汇总
几种动态加载的比较 1.Tinker 用途:热修复 GitHub地址:https://github.com/Tencent/tinker/ 使用:http://www.jianshu.com/p/f6 ...
- iOS dealloc 不被调用的问题
最近项目中老是无缘无故的出现一下奔溃.查看一下堆栈信息,指针的指向都有,但还是奔溃.所以第一个怀疑出现野指针引起的问题.然后调试代码中的一下dealloc函数.好多对象在释放之后都没掉用.顿时吓出一身 ...
- bzoj 1070 [SCOI2007]修车
最小费用最大流. 将每个技术人员拆成车数个点,技术人员i的第j个点代表技术人员i修的倒数第j辆车. 源点向所有技术人员点连一条容量为1费用为0的边. 所有技术人员点向所有车点连边:技术人员i的第j个点 ...
- jquery插件——检测DOM元素是否在浏览器可视范围之内
引言 web应用中有很多地方会用到打点,用来检测用户行为,今天就做了个打点相关的需求,为了统计一个广告给用户的展示次数,每次用户请求完成并且渲染完成之后就算一次成功的展示,其实有时候这个广告还没有在用 ...
- pip apt source images
~/.pip/pip.conf [global] index-url = https://pypi.douban.com/simple download_cache = ~/.cache/pip [i ...
- 通过SmartGit把java maven项目传到码云
一.首先先在码云上新建一个项目 二.复制项目的链接 三.打开SmartGit,点击clone 4.把复制的项目链接粘上去 5.然后点两次next,选择一个路径,finish 6.打开刚刚选择的路径,我 ...
- iBatis.net 循环iterate,没有foreach
3.9.4. Iterate Element This tag will iterate over a collection and repeat the body content for each ...
- React.js入门笔记(再续):评论框的实现
本案例来自React.js中文官网对应内容. 一. 运行环境 <link rel="stylesheet" type="text/css" href=&q ...
- sublime 中 pyv8 binary 报错怎么处理?
,sublime text 在安装插件的时候,尤其是Emmet的时候,经常会报一个错误--please wait a bit whilePyV8 binary is being downloaded, ...
- Rss 订阅:php动态生成xml格式的rss文件
Rss 简介: 简易信息聚合(也 叫聚合内容)是一种描述和同步网站内容的格式.使用RSS订阅能更快地获取信息,网站提供RSS输出,有利于让用户获取网站内容的最新更新.网络用户可以在客户端借助于支持RS ...