iOS中的ARC---内存管理的思考方式
来源:互联网 发布:北大青鸟java好学吗 编辑:程序博客网 时间:2024/06/05 06:05
本文参考:《objective-c高级编程》
一、引用计数式内存管理的思考方式
①自己生成的对象,自己持有
②非自己生成的对象,自己也能持有
③不再需要自己持有的对象时,释放
④非自己持有的对象,无法释放
以下逐一做讲解:
①自己生成的对象,自己持有
/* alloc * new * copy * mutableCopy*///自己生成,并持有对象id obj1 = [[NSObject alloc] init];id obj2 = [NSObject new];
②非自己生成的对象,自己也能持有
//取得非自己生成并持有的对象,obj不持有该数组id obj = [NSMutableArray array];//obj持有数组[obj retain];
③不再需要自己持有的对象时,释放
id obj1 = [[NSObject alloc] init];[obj release];
④非自己持有的对象,无法释放
id obj1 = [[NSObject alloc] init];[obj release];[obj release]; //wrong
⑤autorelease
//如果要用某个方法生成对象,并将其返还给该方法的调用方。- (id)allocObject { //自己生成并持有对象 id obj = [[NSObject alloc] init]; return obj;}//注意命名规则,不能加alloc- (id)Object { //自己生成并持有对象 id obj = [[NSObject alloc] init]; //取得的对象存在,但自己不持有对象。autorelease使对象在超出指定的生存范围时能够自动并正确的释放(调用release方法) [obj autorelease]; return obj;}
使用以上两种方式的区别:
{ [obj allocObject];}{ [obj object]; [obj retain];}
二、alloc/retain/release/dealloc的实现
NSObject类的Foundation框架没有公开。此处是使用GNUstep来参考的(它是Cocoa框架的互换框架)
1.先看看GNUstep内部的实现(简单说明):
①alloc:
alloc—>allocWithZone—>NSAllocateObject
NSAllocateObject:(通过NSZoneMalloc函数分配存放对象所需的内存空间,之后将该内存空间置0,最后返回作为对象而使用的指针)
NSZone:为了防止内存碎片化而引入的结构,对内存分配的区域本身进行多重化管理,根据使用对象的目的、对象的大小分配内存,提供了使用效率。
结论:
alloc类方法中,用一个结构体中的NSUInteger retained来保存引用计数,并将其写入对象内存的头部。
②retain/release
③dealloc
dealloc—>NSDeallocateObject(self)
2.苹果的实现
苹果内部不是把retain值写在对象的头部,它是采用引用计数表来管理引用计数,两者对比一下:
①写在头部:
a)少量代码完成
b)能够统一管理引用计数和对象使用的内存块
②引用计数表
a)分配内存时无需考虑内存块头部
b)表中存有内存块地址,可以从各个记录追溯到各个对象的内存块(这个很好,当出现故障使内存块损坏时,可以通过表来确认内存块的位置)
三、详细解释autorelease
1.首先看看C语言:
{ int a;}//超出{}作用域后,变量a被废弃,不可访问
2.OC中类似作用域的东西:NSAutoreleasePool
作用:相当于{},废弃NSAutoreleasePool对象时,调用它内部的对象的release方法
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; id obj = [[NSObject alloc] init]; [obj autorelease]; [pool drain];
PS:大量的创建NSAutoreleasePool对象,但是不废弃它,它内部的对象就不会被释放。有时会造成内存不足的现象(例如,读入大量图片的同时改变尺寸)
3.autorelease的实现
①先看看GUNstep如何实现的
autorelease实例方法的本质就是调用NSAutoreleasePool对象的addObject方法
-(id) autorelease { [NSAutoreleasePool addObject:self];}//GNUstep中使用的是连接链表,就好比在NSMutableArray中添加一个对象-(void) addObject:(id) obj { [array addObject:obj];}//当调用drain方法时[pool drain];-(void) drain { [self dealloc];}-(void) dealloc { [self emptyPool]; [array release];}-(void) emptyPool { [obj release];}
②苹果的实现和以上原理相同,此处不讲了。
PS:
//发生异常//无论哪个对象调用autorelease,实际上都是调用NSObject类的autorelease实例方法。但是对于NSAutoreleasepool,这个实例方法已经被它重载,运行时就会出错。NSAutoreleasepool *pool = [[NSAutoreleasepool alloc] init];[pool autorelease];
- iOS中的ARC---内存管理的思考方式
- 内存管理的思考方式
- OC的内存管理方式----MRC & ARC
- iOS内存管理--ARC
- iOS ARC内存管理
- iOS arc 内存管理
- iOS夯实:ARC时代的内存管理
- iOS夯实:ARC时代的内存管理
- iOS ARC自动管理内存的坑
- 关于OC中的Block使用以及ARC和MAR下的内存管理方式
- 关于OC中的Block使用以及ARC和MAR下的内存管理方式
- iOS学习 ARC内存管理
- ios 自动内存管理 ARC
- iOS ARC内存管理基本原理
- iOS ARC内存管理总结
- iOS--内存管理和ARC
- ios arc下内存管理
- iOS ARC 内存管理要点
- ZOJ 2972-Hurdles of 110m(背包dp)
- 为什么工程师需要花时间积累
- fragment嵌套使用时getFragmentManager.findFragment()为空的问题
- 轻量级队列工具Httpsqs
- 数据结构之线性表(单链表)
- iOS中的ARC---内存管理的思考方式
- 轰轰烈烈的软考结束了
- GCD介绍
- Java并发编程的特性
- 机器学习之1——线性回归
- JAVA基础学习笔记(2):八种基本数据类型
- [Lua]Lua语言基础汇总 -- 函数
- java中leetcode之Reverse Words in a String
- array [].Getlength与array[].length