OS X内存管理:从源码进行分析(一)
2015-08-31 09:24
295 查看
通过对《Objective-C高级编程》的学习,就来总结一下。
在Objective-C中的内存管理中,autorelease就是自动释放,看上去很像ARC对不对?但是呢,却并不是,其实有点像我们曾经在学习C语言中的局部变量
首先看一个源代码
这个源代码实际是调用了 NSObject类的autorelease方法。
从以上这个代码中我们就可以分析出来,其实autorelease实际上就是调用了NSAutoreleasePool中的addObject方法
看到了以上的内容,我们就需要详细的探讨一下NSAutoreleasePool的实现原理。以下是我摘要的源代码,因为NSAutoreleasePool的源代码的实现太复杂了,所以这里的源代码是经过简化后的
NSAutoreleasePool.m addObject
addObject 类方法调用正在使用的NSAutoreleasePool对象的addObject,这句话可能会有一些难理解,没关系,接着看一组源代码。
通过上面的代码我们就可以看出,被赋予pool变量,那么就是正在使用NSAutoreleasePool的实例化对象。
在我自己学习的过程中,还看到另外一种嵌套的方式
在这种嵌套结构中,pool2为NSAutoreleasePool的使用对象,遵循使用最内测的对象想这个原则。
看一下addObject的实现原理。其实就是调用了array的addObject方法
以上就是GNUstep实现,其实GNUstep使用的就是连接列表,这跟NSNutableArray对象的中追加的原理是一样的,就是说如果我们调用了autorelease方法,这个调用autorelease方法的对象就会被追加到NSAutoreleasePool的数组中
通过drain就可以删除正在使用NSAutoreleasePool的对象
看一下drain的实现原理
通过每次的循环都在调用release方法来实现释放。
首先先来看一下NSAutoreleasePool类方法和autorelease方法的运行过程。以及和从从从c++的对象关系
在Objective-C中的内存管理中,autorelease就是自动释放,看上去很像ARC对不对?但是呢,却并不是,其实有点像我们曾经在学习C语言中的局部变量
GNUstep的实现
就下来就详细的总结一下autorelease的实现原理。由于NSObject类的Foundation框架并没有被开源,所以我们就研究一下GNUstep这个开源软件。首先看一个源代码
[obj autorelease]
这个源代码实际是调用了 NSObject类的autorelease方法。
-(id)autorelease { [NSAutoreleasePool addObject:self]; }
从以上这个代码中我们就可以分析出来,其实autorelease实际上就是调用了NSAutoreleasePool中的addObject方法
看到了以上的内容,我们就需要详细的探讨一下NSAutoreleasePool的实现原理。以下是我摘要的源代码,因为NSAutoreleasePool的源代码的实现太复杂了,所以这里的源代码是经过简化后的
NSAutoreleasePool.m addObject
+(void)addObject:(id)anObj { NSAutoreleasePool *pool = 取得我们正在运用的NSAutoreleasePool; if(pool!=nil){ [pool addObject: anObj]; } else { NSLog(@"NSAutoreleasePool对象不存在"); } }
addObject 类方法调用正在使用的NSAutoreleasePool对象的addObject,这句话可能会有一些难理解,没关系,接着看一组源代码。
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; id obj = [[NSObject alloc] init]; [obj autorelease];
通过上面的代码我们就可以看出,被赋予pool变量,那么就是正在使用NSAutoreleasePool的实例化对象。
在我自己学习的过程中,还看到另外一种嵌套的方式
NSAutoreleasePool *pool0 = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init]; id obj = [[NSObject alloc] init]; [obj autorelease]; [pool2 drain]; [pool1 drain]; [pool0 drain];
在这种嵌套结构中,pool2为NSAutoreleasePool的使用对象,遵循使用最内测的对象想这个原则。
看一下addObject的实现原理。其实就是调用了array的addObject方法
-(void)addObject :(id)anObj { [array addObject : anObj]; }
以上就是GNUstep实现,其实GNUstep使用的就是连接列表,这跟NSNutableArray对象的中追加的原理是一样的,就是说如果我们调用了autorelease方法,这个调用autorelease方法的对象就会被追加到NSAutoreleasePool的数组中
[pool drain];
通过drain就可以删除正在使用NSAutoreleasePool的对象
看一下drain的实现原理
-(void)drain { for(id obj in array){ [obj release]; } [array release]; }
通过每次的循环都在调用release方法来实现释放。
苹果的实现
以下为objc4库中的autorelease实现原理class AutoreleasePoolPage { static inline void *push() { //在这里进行NSAutoreleasePool的生成 } static inline void *pop() { //废弃掉NSAutoreleasePool类对象 releaseAll(); } static inline id autorelease(id obj) { //这里就相当于NSAutoreleasePool类的addObject方法 AutoreleasePoolPage * autoreleasePoolPage = 取得正在使用AutoreleasePoolPage类的对象; autoreleasePoolPage->add(obj); } id *add(id obj) { //讲对象追加到数组中 } void releaseAll() { //调用release实例 } } void *obj_ autoreleasePoolPush(void) { return autoreleasePoolPage::push(); } void *obj_ autoreleasePoolPop(void) { return autoreleasePoolPage::pop(void *ctxt); } void *obj_ autorelease(id obj) { return autoreleasePoolPage::autorelease(obj); } c++中虽然有类似NSNutableArray的动态数组,但是行为却和GNUstep的实现完全不同。
首先先来看一下NSAutoreleasePool类方法和autorelease方法的运行过程。以及和从从从c++的对象关系
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//相当于obj_ autoreleasePoolPush()
id obj = [[NSObject alloc] init];
[obj autorelease];
//相当于*obj_ autorelease(obj)
[pool drain];//相当于*obj_ autoreleasePoolPop(pool)
相关文章推荐
- 竖向tab滑门菜单JS代码
- 12345678各取一个满足4个等式
- vs2012装qt5.5
- Android中XML解析之XMLSAXParser解析
- (int&) 与int(&)
- 【js】弹出文件选择框,可用与文件上传(适配所有浏览器)
- Python 列表学习与使用
- 使用 Sonar 进行代码质量管理
- 串口RTS, CTS的困惑
- ISO18000-6B和ISO18000-6C(EPC C1G2)标准的区别
- social emotion computing-感情的分类
- 属性
- 20140517随感
- C、C++基础知识一
- uval 6425 Intercity
- CentOS 7 上面的samba共享有问题
- Cheatsheet: 2015 08.01 ~ 08.31
- 使用操作系统命令来trace监听
- Leetcode # 169 Majority Element
- java中四种引用类型