初级内存管理

iOS应用程序出现crash(闪退),90%以上是内存问题////其他:数组越界,方法只声明没实现

内存问题体现在两个方面:内存溢出\野指针异常

内存溢出:程序运行超出内存上限

野指针异常:对象空间已经被系统收回,仍然使用指针操作这块内存,代码量越大的程序,越难找出出现野指针的位置

内存管理方式:垃圾回收(gc)     MRC(Manual Reference Count)     ARC(Auto Reference  Count)

垃圾回收:程序员只需要开辟内存空间,不需要⽤代码显⽰地释放,系统来判断哪些空间不再被使用,并回收这些内存空间,以便再次分配。整个回收的过程不需要写任何代码,由系统⾃动完成垃圾回收。Java开发中一直使⽤用的就是垃圾回收技术。

Manual Reference Count,⼈⼯引用计数:内存的开辟和释放都由程序代码进⾏行控制。相对垃圾回收来说,对内存的控制更加灵活,可以在⾃己需要释放的时候及时释放,对程序员的要求较高,程序员要熟悉内存管理的机制。

Auto Reference Count,⾃自动引⽤用计数:iOS 5.0的编译器特性,它 允许⽤用户只开辟空间,不用去释放空间。它不是垃圾回收!它的本质 还是MRC,只是编译器帮程序员默认加了释放的代码。

iOS支持两种内存管理方式:ARC和MRC

MRC的内存管理机制是:引用计数

ARC是基于MRC的.

影响引用计数的方法 +alloc   -retain   -copy     -release    -autorelease

+alloc :开辟内存空间,让被开辟的内存空间的引用计数变为1,这是从0到1得过程

-retain :引用计数加1,如果内存空间之前引用计数为1,retain之后变为2,如果引用计数为5,retain之后变为6

-copy: 把某一内存区域的内容拷贝一份,拷贝到新的内存空间里 去,被拷贝区域的引⽤计数不变,新的内存区域的引⽤计数为1。

-release:引⽤计数减1,如果内存空间之前引⽤计数为4,release之后变为3,如果之前引⽤计数为1,release之后变为0,内存被系 统回收。

-autorelease:未来的某⼀时刻引⽤用计数减1。如果内存之前引⽤用计 数为4,autorelease之后仍然为4,未来某个时刻会变为3。

dealloc

-dealloc是继承⾃父类的⽅法,当对象引⽤用计数为0的时候,由对

象⾃动调用。 我们可以在dealloc中打印⼀句话,验证对象引用计数是否降为0.

- (void)dealloc{
    NSLog(@“%@被销毁了”,self);
    [super dealloc];

}

autoreleasepool的使用

通过autoreleasepool控制autorelease对象的释放。

向⼀个对象发送autorelease消息,这个对象何时释放,取决于 autoreleasepool。

NSAutoreleasePool *pool= [[NSAutoreleasePool alloc]init];

Person *p = [[Person alloc]init];//retainCount为1

[p retain];//retainCount为2

[p autorelease];//retainCount为2 未来的某个时刻释放 [pool release];

NSLog(@”%d”,[p retainCount]);//打印结果为1

NSAutoreleasePool *pool= [[NSAutoreleasePool alloc]init];和

[pool release];就像一对括号,[xxx autorelease];必须写在两者之 间。

[xxx autorelease];出现在了两者之间,pool就会把接收 autorelease的对象给保存起来(以栈的方式,把对象压⼊栈)

当[pool release];的时候,pool会向之前保存的对象逐一发送 release消息(对象出栈,越晚autorelease的对象,越早接收 release消息)。

在iOS5之后,不再推荐使⽤用NSAutoreleasePool类,使⽤用

@autoreleasepool{}替代。

之前写在NSAutoreleasePool *pool= [[NSAutoreleasePool alloc]init];和[pool release];之间的代码,需要写在 @autoreleasepool{}的⼤大括号⾥里。

出了大括号,⾃自动释放池才向各个对象发送release消息。

内存管理原则

引⽤用计数的增加和减少相等,当引⽤用计数降为0之后,不应该再使 ⽤用这块内存空间。

凡是使用了alloc、retain或者copy让内存的引⽤用计数增加了,就需 要使⽤用release或者autorelease让内存的引用计数减少。在⼀一段代码内,增加和减少的次数要相等。

 copy

-跟retain不同,⼀个对象想要copy,⽣生成⾃己的副本,需要实现 NSCopying协议,定义copy的细节(如何copy)。如果类没有接 受NSCopying协议⽽给对象发送copy消息,会引起crash。

iOS学习笔记---oc语言第九天的更多相关文章

  1. iOS学习笔记---oc语言第一天

    第一讲 初始类和对象 c语言的超集,允许在oc中使用c语言源代码.编译器兼容c语言程序 具备完善的面向对象特性 包含一个运行时系统 类库丰富 面向对象编程 oop 面向对象语言:c++  java   ...

  2. iOS学习笔记---oc语言第五天

    字典,数组 ,集排序 一.字典类 存储以下数据 name:张三; sex:男;age:18 film:风暴; playcount:10000次;price:60元 字典类用于保存具有映射关系(key- ...

  3. iOS学习笔记---oc语言第四天

    字符串 数组 一.使用苹果帮助文档 学会使⽤用苹果帮助⽂文档是开发者的⼀一项技能 Inherits from 继承⾃自 Conforms to 遵循什么协议 Framework 属于哪个框架 Avai ...

  4. iOS学习笔记---oc语言第三天

    继承.初始化方法 一.继承 继承的上层:父类  继承的下层:子类 继承是单向的,不能相互继承 继承具有传递性:A继承于B,B继承于C,A具有B和C的特征和行为 子类能继承父类全部的特征和行为(私有变量 ...

  5. iOS学习笔记---oc语言第六天

    Block .数组高级 block本质上就是匿名函数(没有名称的函数) block语法和函数指针很相似 回顾函数 函数:C语⾔中,实现某一类功能的代码段. 完整的函数包含两部分:函数声明.函数定义 函 ...

  6. iOS学习笔记---oc语言第二天

    实例变量与方法 一.实例变量的可见度 二.方法 oc中的方法分两种:类方法和实例方法 类方法:只能类使用 eg:+ (id)alloc  注:类方法中不能使用实例变量 实例方法:只能对象使用,eg:- ...

  7. iOS学习笔记---oc语言第十天

    内存管理高级 一 属性的内部实现原理   assign   retain    copy assign 下的属性内部实现 setter方法 @property(nonatomic,assign)NSS ...

  8. iOS学习笔记---oc语言第八天

    属性 能在一定程度上简化代码,并且增强实例变量的访问安全性 属性的声明:使用@property声明属性  eg:@property NSSstring *name;相当于@interface中声明了两 ...

  9. iOS学习笔记---oc语言第七天

    类的扩展 NSDate是Cocoa中用于处理日期和时间的基础类,封装了某一给定的时刻,具体的日期 时间和时区 使用+date方法获取当前日期和时间 NSDate *date = [NSDate dat ...

随机推荐

  1. 国内HTML5前端开发框架汇总

    国内HTML5前端开发框架汇总 Dawei Cheng 程大伟... 于 星期日, 02/12/2012 - 20:53 提交 国外很有多优秀的HTML5前端开发框架相信大家都耳熟能详:JQuery ...

  2. 常州培训 day1 解题报告

    第一题:(骗分容易,AC难.) 题目大意: 给出一个字符串,找出满足条件A的区间的个数.A:字符A,B,C的出现次数相同. 都出现0次也算,区间的长度可以是0(就是只有一个数).30% |S| ≤ 1 ...

  3. C#窗体的加载等待(BackgroundWorker控件)实现

    窗体拉一个Button按钮和一个加载等待显示的label, label默认隐藏,点击按钮时显示这个label,加载完再隐藏 1.工具箱拉BackgroundWorker控件到窗体 2.backgrou ...

  4. for update造成的Oracle锁表与解锁

    我遇到的情况: 当使用select语句查询表时,后面跟着for update , select * from table for update 当修改表中数据,但是没有commit就关掉PL/SQL, ...

  5. jsp作用域

    1.page: JSP页面内所有实例的默认作用域都是page,仅限于本页面使用 2.request: 同一次请求所涉及的服务器资源(可能是页面.Servlet等),例如,程序使用<jsp:for ...

  6. Python中通过多个字符分割(split)字符串的方法

    python中字符串自带的split方法一次只能使用一个字符对字符串进行分割,但是python的正则模块则可以实现多个字符分割 import re re.split('-|_','sharejs_ha ...

  7. 关于java.lang.reflect.InvocationTargetException

    今天遇到java.lang.reflect.InvocationTargetException错误,卡了好一会儿,报错代码 try { Class<?> c= Class.forName( ...

  8. AJAX初步

    1.什么是AJAX 客户端与服务器,可以在[不必刷新整个浏览器]的情况下,与服务器进行异步通讯的技术,即,AJAX是一个[局部刷新]的[异步]通讯技术: AJAX不是全新的语言,是2005年Googl ...

  9. 嵌套遍历<s:iterator>map=new TreeMap(string,Map(string,User))

    //嵌套遍历,先给外层的map(假设是放在root中的,如果放在context的map中,要加#)取个别名,放到Actioncontext中 <s:iterator value="ma ...

  10. 《day06---面向对象入门》

    /* java开发流程:思路. 案例:对数组操作.获取最大值. 思路: 1,一组数,要获取最大值,比较. 2,怎么比较?挨个比较,要获取数组中的每一个数据都要比较. 3,比较完,记录下来比较大的数据, ...