OC 内存管理:MRC与ARC

内存中的五大区域:

栈区,堆区,BBS段,数据段和代码段,其中除了堆区以外,其他区域的内存管理由系统自行回收

OC对象是存储在堆区的,所以OC的内存管理主要是对”堆区中的OC对象”进行管理

内存管理中的几个概念:

->引用计算器:既retainCount,每个OC对象内部都有1个8字节空间用来存储retainCount,表示有多少”人”正在使用;

对象刚被创建时,默认计数值就为1,当计数值为0时,系统会自动调用dealloc方法将对象销毁

引用计数器的用法:给对象发送相应的技术操作来改变计数器的值

retain消息:使计数器+1

release消息:使计数器-1

retainCount消息:得到当前当前retainCount的值

->野指针:没有初始化的指针变量

->僵尸对象:指一个对象已经被回收,但其数据还存在内存中

僵尸对象有可能可以访问,也有可能不能访问,取决于所占用空间是否已被重新分配.然而,对象一旦被回收就不该再被访问,此时可以开启僵尸对象检测,这样系统会自动检查是否为僵尸对象,但同时也会降低执行效率.

->内存泄露:指对象没有在该回收的时候被回收,而是一直驻留在内存中,直到程序结束的时候才被释放

内存管理的分类:

->MRC:Manual Reference Counting,既手动内存管理

对引用计数器的操作全由程序员亲自完成

->ARC:Automatic Reference Counting,既自动内存管理

(垃圾回收不能在iOS系统使用,故此处暂不讨论)

系统会依照程序员的要求自动改变引用计数器的值(Xcode6开始,默认使用ARC)

手动内存管理:

->手动内存管理的原则:

1)一旦创建一个对象,这个对象的引用计数器的值就为1,所以必须要匹配1个release

2)只有在多1个人使用这个对象的时候才retain

只有在烧1个人使用这个对象的时候才release

3)retain的次数要和release次数相匹配

4)永远不要手动调用对象的dealloc方法,而是让系统自动调用

->手动内存管理中内存泄露的几种情况:

1) retain和release不匹配,retain多余release导致的内存泄露;
2) 对象使用过程中,没有被release,而被赋值为nil;

3) 在方法中不当的使用了retain;

手动内存管理的关键就是防止内存泄露!!!!!防止内存泄露要记住:

1) 谁创建”alloc","new",谁"release";

2) 谁”retain",谁"release";

->多对象的手动内存管理:

当B类作为A类属性时,要防止内存泄露,则A类的setter方法应为:

其中setter方法实现还可写成:

以上是标准的MRC内存管理代码.

->循环retain问题:

1) 遇到的问题:

当两个对象相互引用的时候.
    A对象的属性指向B对象, B对象的属性指向A对象.

这个时候,如果两边都使用retain.就会出现内存泄露. 都回收不了.

2) 解决方案:

1端使用retain,1端使用assign.(请查看@property带参数用法的相关内容)

需要注意的是: 使用assign的那1段,dealloc中不需要再去release这个对象了.

->自动释放池(autorelease)

1)原理:

存储在自动释放池的对象,在自动释放池销毁时,会自动调用该对象的release方法,故将对象存储在自动释放池中,就不需要再写release

2)创建方法:

@autorelease

{

} //大括弧表示自动释放池的范围

3)将对象放入的方法:

在自动释放池的范围中调用对象的autorelease方法.注:autorelease的返回值是对象本身,所以我们可以这样创建对象:

@autorelease

{

类型 *对象 = [类名 alloc] init] autorelease];

}

4)使用注意:

a.只有在自动释放池中调用了对象的autorelease方法,这个对象才会被存储到这个自动释放池之中

b.
对象的创建可以在自动释放池的外面,在自动释放池之中,调用对象的autorelease方法,就可以将这个对象存储到这个自动释放池之中.

c.
当自动释放池结束的时候.仅仅是对存储在自动释放池中的对象发送1条release消息 而不是销毁对象.

d.
如果在自动释放池中,调用同1个对象的autorelease方法多次.就会将对象存储多次到自动释放池之中.在自动释放池结束的时候.会为对象发送多条release消息.那么这个时候就会出现僵尸对象错误.

e.
自动释放池可以嵌套.调用对象的autorelease方法,会讲对象加入到当前自动释放池之中,只有在当前自动释放池结束的时候才会像对象发送release消息.

5)使用规范:

我们一般情况下,写1个类.会为我们的类写1个同名的类方法,用来让外界调用类方法来快速的得到1个对象.应遵守规范:使用类方法创建的对象,要求这个对象在方法中就已经被autorelease过了.这样,我们只要在自动释放池中, 调用类方法来创建对象, 那么创建的对象就会被自动的加入到自动释放中.

自动内存管理:

->自动内存管理原则:
编译器会自动的在合适的地方插入retain、release、autorelase代码;编译器自动为对象做引用计数. 而作为开发者,完全不需要担心编译器会做错(除非开发者自己错用了ARC).

->强指针与弱指针:

强指针:默认情况下,我们声明的指针都为强指针,也可以使用__strong来显示的声明指针为强指针.

弱指针:使用__weak关键字修饰的指针,例如 __weak Person *p;

作用与区别:在ARC模式下,强指针与弱指针用来作为回收对象的标准,当1个对象即使用弱指针指向,但没有任何强指针指向时就会被立即回收,此时该弱指针会被自动设置为nil.

->ARC模式下的循环引用:

在ARC机制下,如果出现了循环引用,既A对象中有1个属性是B对象. B对象中有1个属性是A对象.此时如果两边都为strong.就会发生内存泄露.

解决方案:1端使用strong 另外1端使用weak

MRC和ARC的转换与兼容:

#  ARC兼容MRC的类

target --> Build Phaese   --->   Compiler Sources --> Compiler Flags

让程序兼容ARC和非ARC部分。
转变为非ARC  -fno-objc-arc
转变为ARC的, -f-objc-arc

#  MRC转ARC

Xcode —> refactor  -->   Convert to Objective-C ARC   选中要装换的target -->  调校代码

时间: 2024-08-05 19:37:00

OC 内存管理:MRC与ARC的相关文章

Objective-c的内存管理MRC与ARC

Objective-c的内存管理MRC与ARC Objective-c中提供了两种内存管理机制MRC(MannulReference Counting)和ARC(Automatic Reference Counting),分别提供对内存的手动和自动管理,来满足不同的需求.注意的是Xcode 4.1及其以前版本没有ARC,MRC与ARC的区别如图1所示.需要理解MRC,但实际使用时强推ARC. 图1  MRC与ARC区别示意图   1. Objective-c语言中的MRC(MannulRefer

iOS-旧项目中手动内存管理(MRC)转ARC

在ARC之前,iOS内存管理无论对资深级还是菜鸟级开发者来说都是一件很头疼的事.我参 加过几个使用手动内存管理的项目,印象最深刻的是一个地图类应用,由于应用本身就非常耗内存,当时为了解决内存泄露问题,每周都安排有人值班用 Instruments挨个跑功能,关键是每次都总能检查出来不少.其实不管是菜鸟级还是资深级开发者都避免不了写出内存泄露的代码,规则大家都懂,可是 天知道什么时候手一抖就少写了个release? 好在项目决定转成ARC了,下面将自己转换的过程和中间遇到的问题写出来和大家共享,希望

内存管理-MRC与ARC详解

Objective-C提供了两种内存管理机制MRC(Mannul Reference Counting)和ARC(Automatic Reference Counting),为Objective-C提供了内存的手动和自动管理.下面我们来讲解MRC和ARC的基本概念以及自己的理解,欢迎大家指正!!! 一.前言 在讲述MRC和ARC之前,我们先来看一下Objective-C的引用计数式的内存管理方式.下面是一些特点: 自己生成的对象,自己持有.(通过alloc/new/copy/mutableCop

OC内存管理(MRC)

首先说明一下几块存储区域:栈区(局部变量.函数参数值).堆区(对象.手动申请/释放内存).BSS区(未初始化的全局变量.未初始化的静态数据).常量区(字符串常量以及初始化后的全局变量.初始化后的静态数据).代码区(存放函数体的二进制代码) 1.为什么需要内存管理 由于移动设备的内存极其有限,所以每个APP所占的内存也是有限制的,当某个APP所占用的内存超过系统规定限定内存大小时,系统就会发出内存警告,系统会向该APP发送Memory Warning消息.收到此消息后,需要该APP回收一些不需要再

iOS开发之oc(十一)--内存管理MRC

掌握内容 >理解内存管理的原理 >掌握手动内存管理MRC >掌握内存管理在实际工程中的使用 (一) 1.理解部分 1.1内存管理 (传统内存管理demo) 1.1.1内存管理做了一件什么事? 内存管理就是确保开辟的堆空间得到正确的释放 如果堆空间没有释放,称为内存泄露 使用已释放的堆空间,称为提前释放 重复释放同一个空间,称为重复释放 1.1.2传统内存管理的困境 (1)当我们要释放一个堆,首先要确定使用这个堆的指针,都访问完毕,避免提前释放. (2)释放指针指向的堆空间,首先要确定那些

OC内存管理-1

栈区:从高到低分配 堆区:从低到高 BSS段:没有初始化的 数据区: 代码段: OC内存管理方式: 1 MRC 手动内存管理 2 ARC 自动内存管理 nil是给对象赋空值 下个有道云笔记 内存管理 一.总结: 1.只有OC对象才需要内存管理,基本数据类型无效 2.OC对象存放在堆里面 3.非OC对象一般放在栈里面(栈内存会被系统自动回收) 二.引用计数器: 1.每个OC对象都有自己的引用计数器 2.它是一个整数(int) 3.表示有多少人正在使用这个对象 4.每个OC对象都有4个字节的存储空间

OC内存管理相关整理

OC内存管理 一.基本原理 (一)为什么要进行内存管理.内存管理的目的是什么? 由于移动设备的内存极其有限,所以每个APP所占的内存也是有限制的,当app所占用的内存较多时,系统就会发出内存警告,这时需要回收一些不需要再继续使用的内存空间,比如回收一些不再使用的对象和变量等. 管理范围:任何继承NSObject的对象,对其他的基本数据类型无效 管理目的: 1.不要释放或者覆盖还在使用的内存,这会引起程序崩溃: 2.释放不再使用的内存,防止内存泄露.(ios程序的内存资源很是宝贵.) 本质原因是因

OC内存管理详解

前言 由于移动设备的内存有限,所以我们需要对内存进行严格的管理,以避免内存泄露造成资源浪费.在OC中,只有对象才属于内存管理范围,例如int.struce等基本数据类型不存在内存管理的概念.在iOS开发中,对内存的管理实际上就是对引用计数器的管理. OC内存管理的三种方式 自动垃圾收集(Automatic Garbage Collection): 手动引用计数器(Manual Reference Counting)和自动释放池: 自动引用计数器(Automatic Reference Count

OC内存管理

OC内存管理 一.基本原理 (一)为什么要进行内存管理. 由于移动设备的内存极其有限,所以每个APP所占的内存也是有限制的,当app所占用的内存较多时,系统就会发出内存警告,这时需要回收一些不需要再继续使用的内存空间,比如回收一些不再使用的对象和变量等. 管理范围:任何继承NSObject的对象,对其他的基本数据类型无效. 本质原因是因为对象和其他数据类型在系统中的存储空间不一样,其它局部变量主要存放于栈中,而对象存储于堆中,当代码块结束时这个代码块中涉及的所有局部变量会被回收,指向对象的指针也