OC-7-内存管理
课程要点:
- 内存管理的必要性
- MRC(手动管理)
- 自动释放池
- ARC是怎么对内存进行管理的
内存管理的必要性
OC是一门面向对象的语言,在软件运行过程中会创造大量的对象,每创建一个对象系统就会给其分配一块内存,如果开发者不对创建的这些对象进行管理,当这个软件占用系统20兆内存时,iPhone开始发出内存警告,如果占用30兆内存时,iPhone OS会关闭应用程序。为了避免这种情况我们需要对咱们创建的对象进行管理。管理方式有MRC(手动管理)、ARC(自动管理)。
MRC在11年以后,渐渐的被开发者所抛弃,但为什么开发者还要学习这个东西呢。举个例子,就好比小时候家里的各种物品一般都是母亲进行整理,我们基本上很少管这些事,但我们多多少少都知道母亲整理物品的习惯,我们需要找什么东西时,只要按照母亲的习惯去找就行。如果一点都不知道母亲整理物品的习惯,这对我们找东西将会很麻烦。
在比较正规的公司,他们对项目的要求是很严格的。项目做完他们会对你做的项目进行一个内存检测,如果过高,他们会让你进行重构,此时如果你不知道你的项目是怎么管理内存的,那不是就是抓瞎么。
MRC
在WWDC2011和iOS5之前,苹果开发者一直都在使用MRC进行内存管理。
因为现在Xcode创建的工程默认都是由ARC管理的。所以在使用MRC之前要关闭ARC,如图所示

转过MRC后看代码:
PS:我之前已经创建过Person类,所以采用下面代码之前先在你项目里新建一个Person类
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool { /* object-c 使用引用计数的方式管理内存。当我们使用一个指针指向一块内存的时候,应该对这块内存做retain操作,那么引用计数加一。当我们不再使用这个指针指向这块内存,应该对这块内存做release操作,那么引用计数减一。这样可以使引用计数值一直保持等于指向这块内存的指针数量。retainCount返回当前内存的引用计数值。当内存被开辟后,默认的引用计数为1 。
*/ //产生一个新的对象,此时不用release,因为新建的对象引用为1,不需要为第一个指向这个对象的指针额外加一计数。
Person *person1 = [[Person alloc]init]; NSInteger count = [person1 retainCount]; //赋值后count等于1
NSLog(@"%ld",count); NSObject *person2 = person1; [person2 retain]; count = [person2 retainCount]; //赋值后count等于2
NSLog(@"%ld",count); //需要认识的是,不论使用object1还是object2调用retain方法都是一样的,因为两者指向同一块内存,计数增加减少都是以内存为对象的
[person1 release],person1 = NULL; //当object2 release之后,这个对象的引用计数为0,内存被释放,同时会调用这个对象的delloc方法。delloc方法是每一个类都有的隐式方法。当用这个类创建的对象的retainCount为0的时候才会调用,自己可以在.m文件中将他重写.如果此时你打印retainCount你会发现他的值依然是1,这里大家只需要记住系统内部会对咱创建的对象进行操作,才会造成这种现象。不必深究。
[person2 release],person2 = NULL;
/*
* object release 之后为什么还要把对象给置空 因为对象其实就是一个指针,指针指向的是一块内存,release仅仅是把这个内存释放了,也就是说release以后系统把这块内存给回收了。但此时指针指向得还是这块内存。这是不符合逻辑的,所有我要把指针给置空,至此才切断了这个指针与对象的所有关系。 */ }
return ;
}
输出结果:
2015-11-27 17:47:32.162 Test[2333:228117] 1
2015-11-27 17:47:32.163 Test[2333:228117] 2
Program ended with exit code: 0
重写Person.m里的delloc方法
#import "Person.h" @implementation Person //这是一个隐式方法,也就是苹果在内部已经声明和实现好了,如果我想要使用直接调用便可,如果想改变里面的内容,只需在.m里面把他重写就行。
- (void)dealloc{ NSLog(@"person对象被释放"); [super dealloc]; /*
* 为什么需要调用父类的dealloc方法 子类的某些实例是继承自父类的。因此,我们需要调用父类的dealloc方法,来释放父类拥有的这些对象。 PS:每一个类都有一个父类,用到这个类时不可避免的会用到父类里面的东西,所以咱们在子类里释放内存的时候,要记得通过[super dealloc]来释放掉咱们用到的父类里面的对象。 调用的顺序一般来说调用的顺序是,当子类的对象释放完时,然后再释放父类的所拥有的实例。 */
} @end
输出结果:
-- ::32.355 Test[:]
-- ::32.356 Test[:]
-- ::32.356 Test[:] person对象被释放
Program ended with exit code:
自动释放池:
1、Autorelease pool
自动释放池(Autorelease pool)是OC的一种内存自动回收机制,可以将一些临时变量通过自动释放池来回收统一释放
自动释放池本事销毁的时候,池子里面所有的对象都会做一次release操作
2、autorelease
任何OC对象只要调用autorelease方法,就会把该对象放到离自己最近的自动释放池中(栈顶的释放池)。
自动释放池的使用
//ios5.0新方式
@autoreleasepool
{
//池的区域
}
//ios5.0之前的老方式
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc]init];
//池的区域
[pool release];
自动释放池使用技巧:
PS:已重写person.m的delloc方法,并在里面写上NSLog(@"person对象已释放");如果delloc方法执行,便会有输出。
int main(){
//在MRC中并不是将ARC的代码放在池中便能够自动管理内存,每创建一个对象都有在后面加上autorelease
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc]init];
//不加autorelease,出池后person.m的delloc方法不会执行
Person *person = [[Person alloc]init];
[pool release];
}
此时控制台输出:
Program ended with exit code:
int main(){
//在MRC中并不是将ARC的代码放在池中便能够自动管理内存,每创建一个对象都有在后面加上autorelease
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc]init];
//创建对象时在后面加上autorelease,出池后,person.m里delloc方法执行
Person *person = [[[Person alloc]init] autorelease];
[pool release];
}
此时控制台输出:
-- ::02.287 Test[:] person对象被释放
Program ended with exit code:
以上是个人见解,若有错误欢迎指正,在学习中若有不理解欢迎骚扰 QQ:2314858225
OC-7-内存管理的更多相关文章
- 12.Object-C--浅谈OC的内存管理机制
昨天学习了OC的内存管理机制,今天想总结一下,所以接下来我要在这里bibi一下:OC的内存管理. 首先我要说的是,内存管理的作用范围. 内存管理的作用范围: 任何继承了NSObject的对象,对其他基 ...
- 黑马程序员——OC的内存管理学习小结
内存管理在Objective-C中的重要性就像指针在C语言中的重要程序一样. 虽然作为一门高级语言,但OC却没有内存回收机制.这就需要开发者来对动态内存进行管理.OC中内存管理的范围是:任何继承了NS ...
- OC:内存管理、dealloc方法、copy知识点
属性的声明:使⽤@property声明属性 例如:@property NSString *name: 相当于@interface中声明了两个⽅法(setter.getter): 属性的实现:使⽤@s ...
- OC的内存管理机制
总的来说OC有三种内存管理机制,下面将分别对这三种机制做简要的概述. 1.手动引用计数(Mannul Reference Counting-MRC) mannul:用手的,手工的. 引用计数:reta ...
- OC基础 内存管理
OC基础 内存管理 我们所了解的c语言内存管理,如下: (1)c语言的内存分配:char *p = (char*)malloc(100*sizeof(char)); (2)c语言的内存释放:free ...
- OC的内存管理(一)
在OC中当一个APP使用的内存超过20M,则系统会向该APP发送 Memory Warning消息,收到此消息后,需要回收一些不需要再继续使用的内存空间,比如回收一些不再使用的对象和变量等,否则程序会 ...
- 黑马程序员——OC语言 内存管理
Java培训.Android培训.iOS培训..Net培训.期待与您交流! (以下内容是对黑马苹果入学视频的个人知识点总结) (一)计数器 每个对象内部都保存了一个与之相关联的整数,称为引用计数器,当 ...
- OC的内存管理
摘自:http://blog.csdn.net/hahahacff/article/details/39839571 OC内存管理 一.基本原理 (一)为什么要进行内存管理. 由于移动设备的内存极其有 ...
- OC - 5.内存管理
一.引用计数器 1> 栈和堆 栈 ① 主要存储局部变量 ② 内存自动回收 堆 ① 主要存储需要动态分配内存的变量 ② 需要手动回收内存,是OC内存管理的对象 2> 简介 作用 ① 表示对象 ...
- oc语言--内存管理
一.基本原理 1.什么是内存管理 1> 移动设备的内存及其有限,每个app所能占用的内存是有限制的 2> 当app所占用的内存较多时,系统就会发出内存警告,这是需要回收一些不需要的内存空间 ...
随机推荐
- 【数论】【筛法求素数】【欧拉函数】bzoj2818 Gcd
gcd(x,y)(1<=x,y<=n)为素数(暂且把(x,y)和(y,x)算一种) 的个数 <=> gcd(x/k,y/k)=1,k是x的质因数 的个数 <=> Σ ...
- [CodeChef-DGTCNT]Chef and Digits
题目大意: 若一个十进制数$x$(不含前导零)满足数码$i$恰好出现$t_i$次,则这个数是坏的,否则是好的.求区间$[L,R](1\le L,R\le10^{18})$中有多少好数. 思路: 显然可 ...
- Eclipse编辑jsp卡死解决方案
使用Eclipse编辑jsp.js文件时,经常出现卡死现象,在网上百度了N次,经过N次优化调整后,卡死现象逐步好转,具体那个方法起到作用,不太好讲.将所有用过的方法罗列如下: 1.取消验证 windo ...
- Scala实战高手****第12课:Scala函数式编程进阶(匿名函数、高阶函数、函数类型推断、Currying)与Spark源码鉴赏
/** * 函数式编程进阶: * 1.函数和变量一样作为Scala语言的一等公民,函数可以直接赋值给变量 * 2.函数更常用的方式是匿名函数,定义的时候只需要说明输入参数的类型和函数体即可,不需要名称 ...
- 如何在debug模式下,使用正式的签名文件
有两种方式(在集成第三方库的使用 使用的非常多) 签名配置信息 一是直接按F4,在项目结构面板中进行设置,只要操作两个两个选项卡就好了,signing(生成配置信息)和build types(打包类 ...
- angular get/post 下载 excel
阅读目录 get请求 post请求 最近做项目,就碰到一个导出excel表格的功能.原本是想利用web前台导出excel的,但是最后因为两点放弃了,第一点,因为中文乱码,第二点,有分页(在前台导出ex ...
- iOS:二维码的扫描
iOS 中二维码的扫描借用#import <AVFoundation/AVFoundation.h> 实现,会用到<AVCaptureMetadataOutputObjectsDel ...
- python之web路径扫描工具
# coding: UTF-8 import sys, os, time, httplibimport relist_http=[] #http数组 def open_httptxt(): #打开 ...
- Windows 2003 R2
微软发布Windows Server 2003 R2版的目的是希望透过它填补Windows Server 2003 SP1和Longhorn Server之间的产品发布时间间隔. 微软向产品测试人员表 ...
- 面试题:Java中值传递和引用传递的问题
随便写写留着自己看. 首先,Java的参数传递,不管是基本数据类型还是引用类型的参数,都是按值传递,没有按引用传递! 当一个实例对象作为参数被传递到方法中时,参数的值就是该对象的引用的一个副本.指向同 ...