首先通过GNUstep上得源码来叙述各个函数的实现(GNUstep是Cocoa框架的互换框架,二者的行为和实现方式很相似)

GNUstep源码中NSObject类的alloc方法:

id = obj = [NSObject alloc];

/**********************************/

+(id) alloc{

return [self allocWithZone : NSDefaultMallocZone()];

}

+(id) allocWithZone:(NSZone *) z{

return NSAllocateObject(self,0,z);

}

//NSZone是为了防止内存碎片化而引入的结构,对内存分配的区域本身进行多重画管理

NSAllocateObject函数例如以下:

struct obj_layout{

NSUInteger retained;

}

inline id NSAllocateObject(Class aClass,NSUInteger extraBytes,NSZone *zone){

int size = 计算容纳对象所需的内存;

id new  = NSZoneMalloc(Zone ,size);

memset(new ,0 ,size);

new  = (id) &((struct obj_layout *) new)[1];

}

NSAllocateObject函数通过调用NSZoneMalloc函数来分配存放对象所需的内存空间,之后将该内存空间置为0,最后返回对象而使用的指针.

/**************************/

-(NSUInteger) retainCount{

return NSExtraRefCount(self) + 1;

}

inline NSUInteger NSExtraRefCount(id anObject){

return ((struct obj_layout *) anObject)[-1].retained;

//由对象寻址找到对象内存头部,从而訪问当中的retained变量

}

/***************************/

-(id) retain{

NSInCrementExtraRefCount(self);

return self;

}

inline void NSInCrementExtraRefCount(id anObject){

if((( struct obj_layout *) anObject)[-1].retained == UINT_MAX - 1){

[NSException raise:NSInternalInconsistencyException format:@“NSIncrementExtraRefCount()ask to increment too far”];

(( struct obj_layout *)anObject) [-1].retained++;

}

}

/********************************/

-(void) release{

if(NSDecrementExtraREfCountWasZero(self))

[self dealloc];

}

BOOL NSDecrementExtraREfCountWasZero(id anObject){

if((struct obj_layout *) anObject)[-1].retained == 0){

return YES;

}else{

(struct obj_layout *) anObject)[-1].retained—;

return NO;

}

}

/**********************************/

-(void ) dealloc{

NSDeallocateObject(self);

}

inline void NSDeallocateObject(id anObject){

struct obj_layout *o = &((struct obj_layout *) anObject)[-1];

free(o);

}

以上就是GNUstep中的实现

//

苹果的实现

通过在NSObject类的alloc类方法上设置断点,查看其运行的函数为:

+alloc

+allocWithZone

class_createInstance

calloc

各个方法都调用了_CFDoExternRefOperation函数

/************************************************/

int  _CFDoExternRefOperation(uintptr_t op,id obj){

CFBasicHashRef table = 取得对象所相应的散列表(obj);

int count;

int count;
    switch (op) {
    case OPERATION_retainCount:
     count = CFBasicHashGetCountOfKey(table, obj);
    return count;
     case OPERATION_retain:
    CFBasicHashAddValue(table, obj);
    return obj;
     case OPERATION_release:
    count = CFBasicHashRemoveValue(table, obj);
     return 0 == count;
    }

}

何为散列表

散列表(也叫哈希表)是一种查找算法,与链表、树等算法不同的是。散列表算法在查找时不须要进行一系列和keyword(keyword是数据元素中某个数据项的值,用以标识一个数据元素)的比較操作。

散列表算法希望能尽量做到不经过不论什么比較。通过一次存取就能得到所查找的数据元素,因而必需要在数据元素的存储位置和它的keyword(可用key表示)之间建立一个确定的相应关系,使每一个keyword和散列表中一个唯一的存储位置相相应。因此在查找时,仅仅要依据这个相应关系找到给定keyword在散列表中的位置就可以。这样的相应关系被称为散列函数(可用h(key)表示)。

依据设定的散列函数h(key)和处理冲突的方法将一组keywordkey映像到一个有限的连续的地址区间上,并以keyword在地址区间中的像作为数据元素在表中的存储位置,这样的表便被称为散列表,这一映像过程称为散列,所得存储位置称为散列地址。

由上可知苹果是将计数器保存在引用记数表的记录中

优点:

(1) 对象用内存块的分配无需考虑内存头部

(2) 引用计数表个记录中存有内存块地址,可追溯到个内存块.

转载于:https://www.cnblogs.com/brucemengbm/p/6761113.html

深入解析alloc/retain/release/dealloc实现相关推荐

  1. iOS内存管理——alloc/release/dealloc方法的GNUstep实现与Apple的实现

    关于阅读<Object-C高级编程-iOS与OS X多线程和内存管理>一书后的iOS内存管理系列思考 <关于iOS内存管理的规则思考> <iOS内存管理--alloc/r ...

  2. 在XIB里面关于@property,@synthesize,release,dealloc的怪现象

    在一个XIB中,有一个IBOutlet的UILabel叫 label_ XIB的线已经连好了 IBOutlet UILabel *label_; 如果我定义 @property(nonatomic,a ...

  3. iOS之深入解析alloc、init与new的底层原理

    底层探索 一.对于iOS的底层原理探索,查找到函数所在的源码库,一般有以下方法实现 ① 符号断点 在哪里新建符号断点:选择 Symbolic Breakpoint : 怎么添加符号断点:在Symbol ...

  4. Linked dylibs built for GC-only but object files built for retain/release for architecture x86_64

    编译开源Xcode 插件 SCXcodeSwitchExpander 源码地址: https://github.com/stefanceriu/SCXcodeSwitchExpander 编译环境:X ...

  5. iOS 进阶—— iOS内存管理

    1 似乎每个人在学习 iOS 过程中都考虑过的问题 alloc retain release delloc 做了什么? autoreleasepool 是怎样实现的? __unsafe_unretai ...

  6. ios nslog 例子_iOS 典型内存泄露案例 - zhenshan2013的个人空间 - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...

    最近进行iOS 安全黑匣子的测试,在Demo中通过不断的点击调加密接口,同时通过苹果自带instrument的leak工具监控,发现典型的内存泄漏,监控图如下: 上图中红色的部分表示该操作触发的代码有 ...

  7. [OC学习笔记]自动引用计数

    一.什么是自动引用计数 自动引用计数(ARC,Automic Reference Counting)是指内存管理中对引用采取自动计数的技术. 在Objective-C中采用Automic Refere ...

  8. 【iOS】ARC学习

    前文:引用计数 请先看我的这篇文章: 引用计数 内存管理 1.1 alloc/retain/release/dealloc的实现 在这里,我们使用开源软件GNUstep(GNUstep的源代码虽不能说 ...

  9. ios5 ARC机制介绍和使用

    参考http://www.yifeiyang.net/development-of-the-iphone-simply-1/ http://blog.csdn.net/diyagoanyhacker/ ...

最新文章

  1. poj_3067 树状数组
  2. JavaScript中this工作方式
  3. python能做游戏吗-python能开发游戏吗
  4. svn 文件状态标记含义
  5. 判断一个js对象,是否具有某个属性
  6. 回溯法 -数据结构与算法
  7. 演练:调试多线程应用程序
  8. lodash 学习资料
  9. Memcached主主复制+Keepalived高可用架构
  10. DirectX Audio和DirectShow入门
  11. NLP 事件抽取综述(中)—— 模型篇
  12. 字体的基础知识:英文字体的特征及结构(终于找到了)
  13. 三相电机控制方式入门,看完这一篇就够了
  14. Composition API使用记录
  15. Python入门(二)-编程环境
  16. 前端萌新看过来了—— 0基础1小时vue入门到实战
  17. 《一步一步看源码:Nacos》框架源码系列之一(其1,配置服务源码)
  18. 20220405笔记自勉
  19. 偏向锁的获取和撤销详解
  20. Python小游戏——外星人入侵(保姆级教程)第一章 03设置飞船图片 04创建Ship类

热门文章

  1. 属羊的人2021年冲太岁运势预测
  2. 抓住好资产,让你赚一辈子
  3. 寻找点赞所需的URL
  4. 为什么要使用namedtuple?
  5. 不小心执行了rm-rf,除了跑路,如何恢复?
  6. 本地Nginx+Hosts配置本地前端代码和后端代码联调
  7. CSU计算机图形学复习
  8. smb文件共享_使用SMB文件共享作为存储替代方案
  9. sql初学者指南_使用tSQLt框架SQL单元测试面向初学者
  10. sql错误索引中丢失_收集,汇总和分析丢失SQL Server索引统计信息