OS X内存管理:从源码进行分析(一)
来源:互联网 发布:行知幼稚园 编辑:程序博客网 时间:2024/06/06 05:47
通过对《Objective-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)
- OS X内存管理:从源码进行分析(一)
- Objective-C内存管理:从源码进行分析(二)
- iOS/OS X内存管理(一):基本概念与原理
- iOS/OS X内存管理(一):基本概念与原理
- iOS/OS X内存管理(一):基本概念与原理
- iOS/OS X内存管理(一):基本概念与原理
- iOS/OS X内存管理(一):基本概念与原理
- iOS/OS X内存管理(一):基本概念与原理
- iOS/OS X内存管理(一):基本概念与原理
- iOS/OS X内存管理(一):基本概念与原理
- cocos2d-x 源码分析 : Ref (CCObject) 源码分析 cocos2d-x内存管理策略
- cocos2d-x 源码分析 : Ref (CCObject) 源码分析 cocos2d-x内存管理策略
- cocos2d-x 源码分析 : Ref (CCObject) 源码分析 cocos2d-x内存管理策略
- cocos2d-x 源码分析 : Ref (CCObject) 源码分析 cocos2d-x内存管理策略
- iOS/OS X内存管理(一):基本概念与原理
- iOS/OS X内存管理(一):基本概念与原理
- iOS/OS X内存管理(一):基本概念与原理
- 【Cocos2d-x源码分析】 Cocos2d-x内存管理解析
- Android中XML解析之XMLSAXParser解析
- (int&) 与int(&)
- 使用 Sonar 进行代码质量管理
- 总结四--从14年“暑假”到15年“暑假”
- Android Https相关完全解析 当OkHttp遇到Https
- OS X内存管理:从源码进行分析(一)
- linux ln命令: 链接文件或目录
- 20140514随感
- web工程中获取文件的Inpustream几种方法
- 竖向tab滑门菜单JS代码
- 字符串匹配的KMP算法
- 电量上层统计
- foxmail邮箱 邮件地址信息 以及邮件内容信息的导入导出
- 让程序员跳槽的非钱原因