OC之内存管理



比如植物大战僵尸、开心消消乐,每一个僵尸就是一个对象,每一个方块也是一个对象,既然是对象系统就会分配内存(堆内存),那么死去的僵尸和消除的方块应该如何处理?
iOS系统会给每一个运行的软件一块内存空间。应用程序使用内存超过这个内存空间,程序就会被系统主动关闭
为什么要使用内存管理?
应用程序崩溃%90以上都是内存问题引起的,了解内存管理的原则,能够减少我们程序的出错机率
出现内存问题一般有两个方面:内存溢出、野指针访问
1.内存溢出:
iOS给每个应用程序提供了一定的内存,iPhone 3GS内存30M左右,一旦超出内存上限程序就会crash(崩溃、闪退)
程序开发过程中最占用内存的是图片、音频、视频等资源文件
3.5寸非Retina屏幕像素是320*480,而一张全屏的图片所占的内存(320*480*4)(一个像素占四个字节,存放RGBA),那么同时读取30张图片程序就会崩溃
3.5Retina屏幕640*960
一张全屏图片所占内存空间640*960*4 = 2457600/1024 = 2.4M
内存溢出也就是超出了给你限定的内存区域导致的问题,就跟用容器装水一样,超出了容器的水就会溢出
2.野指针访问:
对象的内存已经被系统回收,仍然使用指针操作这块内存,野指针操作是程序crash的主要原因,代码量越大越难找出野指针的位置,
了解程序内存管理能帮我们提升程序的性能,减少bug调试时间
那么我们如何管理内存?
有创建就要有销毁
所谓的内存管理就是对对象的创建和销毁的过程进行管理
内存管理方式:
1.垃圾回收:(javaC#C++OC(只支持Mac OS))
2.手动管理内存
C语言:malloc free
C++
OCMRCManual Reference Count)手动 引用 计数
3.自动管理内存:ARCAuto Reference Count)自动 引用 计数,iOS 5之后的新特性,并不是垃圾回收
     
垃圾回收机制:
程序员只需要开辟空间,不需要用代码进行释放,系统来判断那些空间不再被使用,并回收这些内存空间,以便再次分配。整个回收的过程不需要写任何代码,由系统自动完成垃圾回收,Java中一直是用的就是这种自动回收技术
     
 MRC
手动引用计数:内存的开辟和释放都有程序的代码控制,相对于垃圾回收机制,MRC对内存的控制更加灵活,可以在需要释放的时候及时释放,对程序员要求较高,程序员要熟悉内存管理机制
 ARC
自动引用计数:
iOS 5的编译器新特性,只允许用户开辟空间,不用释放空间。它不是垃圾回收机制,本质还是MRC,只是编译器帮程序员默认加入了释放的代码
iOS内存管理:
iOS支持三种内存管理:MMRCARC、垃圾回收(Mac OS
MRC的内存管理机制是引用计数机制
AR是基于MRC的。
内存管理机制--引用计数
OC采用引用机制管理对象所占内存
实际开发中,经常遇到多个指针指向同一个内存地址的情况,C语言无法记录内存使用者的个数
计数:计数器,用于统计数字
引用计数:某一块内存,拥有这块内存的拥有者个数
拥有者(owner):使用这块内存区域的对象
NSObject类及其子类都有一个属性,用来记录当前对象的引用计数
OC采用计数机制管理内存,当一个新的引用只想对象时,引用计数器就加1,当不再使用的时候,引用计数就减1,当引用计数为0时,该对象将释放所占有的资源.
生命周期
实例对象的生命周期
出生于alloc方法,死亡于dealloc方法
通过类发送alloc消息获得的实力对象的引用计数赋值为1,当实例对象引用计数为0时,自动对该对象发送dealloc消息
影响引用计数的方法:
+alloc:开辟内存空间,让被开辟的内存空间的引用计数变为1。这是从01的过程。
-retain持有的意思,对象引用计数+1并且拥有该对象的所有权如果对象原来引用计数为1,那么return之后变为2,如果引用计数是5return之后为6.
copy:把某一内存区域的内容拷贝一份,拷贝到新的内存空间里去,被拷贝区域的引用计数不变新的内存区域引用计数变为1,拥有新的被copy出来的对象的所有权。
release:引用计数-1并释放对象的所有权,如果内存空间之前引用计数为4release之后引用计数变为3
autorelease:未来的某一时刻引用计数-1
dealloc:继承自父类(NSObject)的方法,当对象的引用计数为0时,由系统使用该对象调用dealloc方法
dealloc方法我们不能自己调用
        
自动释放池:NSAutoReleasePool
当创建的对象在未来的某个时间销毁时,可以使用autorelease,将对象所有权交给最近的NSAutoReleasePool对象,尽量少使用自动释放池
autoreleasepool控制使用autorelease对象的释放,这个对象何时释放 取决于这个autoreleasepool
新的autoreleasepool写法
 @autoreleasepool{
 Person *person2 =[[Person alloc]init];
[person2 retain];
[person2 autorelease];
}
person引用计数为0,但是nslog之后还是1,因为当当对象引用计数为0时会被释放,而你又输出这个释放对象的这个是访对象的引用计数,也就是这个输出根本不成立,打印出来的东西也毫无意义
内存管理原则
凡是出现alloc、retain、copy的地方,都应该出现release或者autorelease与之对应属性为retain、copy的时候,需要在类的dealloc方法中释放这个属性
凡是使用了alloc、retain、copy让内存的引用计数增加了,就需要使用release或者autorelease让内存的引用减少,在一段代码内增加和减少的次数要相等
copy方法
跟retain不同,一个对象想要copy声称自己的副本,需要遵从NSCopying协议, NSCopying协议中有一个必须实现的协议方法,如果没有遵循 NSCopying协议,挥着诶有实现里面的协议方法,就会导致崩溃,我们需要在copyWithZone这个方法中定义copy的细节

1.属性的内 部实现原理
2.dealloc内部释放实例变量
3.便利构造器方法的实现原理
4.collection的内部管理
属性的语义设置与使用范围
dealloc释放的是类本身的内存。
使用mutable时,复制出的新对象和原来对象的引用计数都为1,新对象release之后就不能再访问
实例变量需要在dealloc中去释放,否则会造成内存泄露
dealloc方法是NSObject的一个实例方法,与alloc的对应,用于回收开辟的内存空间
dealloc方法在对象的引用计数为0时由系统去调用
通常在dealloc中释放类的实例变量
dealloc不能手动调用(永远不要去手动调用)
dealloc中最后一行,必须写[super dealloc]
集合(collection)的内存管理
collection会自动管理添加删除的对象的内存,我们只需要管理集合的生成和释放
添加的元素会被retain
删除的元素会被release
集合释放的时候,会对每一个对象发送release消息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值