alloc & init & dealloc
在Objective-C中,alloc,init和dealloc是经常使用的函数,那么它们内部到底是如何实现的呢?通过查看libobjc运行时库,可以发现他们的工作原理。
1 alloc
alloc的功能就是为对象分配内存,关键代码如下:
if (!UseGC && !zone && fast) {
obj = (id)calloc(, size);
if (!obj) return nil;
obj->initInstanceIsa(cls, hasCxxDtor);
}
在上面的代码中,calloc就是用来位对象分配内存的,并且calloc还会将这块内存区域初始化位0,其中的size就是对象的大小=isa指针(下面介绍) + 对象中的实例变量。为了内存对齐,size的大小可能会包含一些填充字节。分配好的内存被转换为id类型,下面是运行时库中对id类型的定义:
typedef struct objc_object *id;
可以看到,id类型其实就是一个结构体指针,该结构体为objc_object,而struct objc_object的定义为(只展示了struct里面的实例变量,去掉了struct里面的方法):
struct objc_object {
private:
isa_t isa;
}
struct objc_object中的成员变量isa是一个指针,指向的是对象所属类的Class对象。
分配好内存之后,调用obj->initInstanceIsa方法,这个方法的作用就是用该对象所属类的Class对象地址初始化对象的isa指针,类的Class对象地址由参数cls提供。有关对象,对象所属类的Class对象的介绍,可以参看链接:刨根问底Objective-C Runtime(2)- Object & Class & Meta Class。
2 init
init方法很简单,什么也不做,简单的返回对象地址,源码如下:
- (id)init {
return _objc_rootInit(self);
}
id
_objc_rootInit(id obj)
{
// In practice, it will be hard to rely on this function.
// Many classes do not properly chain -init calls.
return obj;
}
3 dealloc
dealloc的作用就是释放内存,关键源代码如下:
id
object_dispose(id obj)
{
if (!obj) return nil; objc_destructInstance(obj); #if SUPPORT_GC
if (UseGC) {
auto_zone_retain(gc_zone, obj); // gc free expects rc==1
}
#endif free(obj); return nil;
}
object_dispose是dealloc用来释放内存所调用的函数,可以看到,object_dispose只是简单的调用了free函数来释放内存。但是在调用free之前,object_dispose调用了objc_destructInstance。objc_destructInstance函数如下:
void *objc_destructInstance(id obj)
{
if (obj) {
// Read all of the flags at once for performance.
bool cxx = obj->hasCxxDtor();
bool assoc = !UseGC && obj->hasAssociatedObjects();
bool dealloc = !UseGC; // This order is important.
if (cxx) object_cxxDestruct(obj);
if (assoc) _object_remove_assocations(obj);
if (dealloc) obj->clearDeallocating();
} return obj;
}
其中标红色的方法会对类中包含的成员变量进行释放,这个释放动作是由编译器来保证的(ARC下),即使overwrite了某个类的dealloc,并且overwrite dealloc时没有对成员变量赋值nil,这个过程也不受影响,照样进行。
最后附上libObjc的下载连接:https://github.com/longv2go/objc4-646
alloc & init & dealloc的更多相关文章
- iOS开发new与alloc/init的区别
[className new]基本等同于[[className alloc] init]: 区别只在于alloc分配内存的时候使用了zone. 这个zone是个什么东东呢? 它是给对象分配内存的时候, ...
- new和alloc init的区别
背景说明,new是较为老式的写法,后来发现只有一个new不好使,才引入了alloc和init这种写 法,保留new一是向后兼容,二是很多时候是一种更简单的写法.其实是一样的,new在内部调用 的all ...
- array 和 alloc init 以及 new 区别
当你使用new.alloc或copy方法创建一个对象时,该对象的引用计数器值为1.当不再使用该对象时,你要负责向该对象发送一条release或autorelease消息.这样,该对象将在其使用寿命结束 ...
- ios alloc init 和 new 的区别
1.在实际开发中很少会用到new,一般创建对象咱们看到的全是[[className alloc] init] 但是并不意味着你不会接触到new,在一些代码中还是会看到[className new], ...
- OC 中new与alloc/init的差别
英文具体解释:http://macresearch.org/difference-between-alloc-init-and-new 1.在实际开发中非常少会用到new.一般创建对象咱们看到的全是[ ...
- new与alloc/init的区别
alloc:分配内存. init:初始化. new:代替上面两个函数:分配内存,并且初始化. 注意: 1.在实际开发中很少会用到new,一般创建对象时我们一般是 [[className alloc]i ...
- [转]iOS开发new与alloc/init的区别
1.在实际开发中很少会用到new,一般创建对象咱们看到的全是[[className alloc] init] 但是并不意味着你不会接触到new,在一些代码中还是会看到[className new], ...
- Objective-C中new与alloc/init的区别
在实际开发中很少会用到new,一般创建对象我们看到的全是[[className alloc] init],但是并不意味着你不会接触到new,在一些代码中还是会看到[className new],还有去 ...
- alloc init初始化后对象依然还在父视图
self.TableView=[[UITableView alloc]init]; ........2个cell //下面但方法和addsubviews方法不一样 [self.view insertS ...
随机推荐
- 各邮箱服务器地址及端口<转>
gmail(google.com) POP3服务器地址:pop.gmail.com(SSL启用端口:995) SMTP服务器地址:smtp.gmail.com(SSL启用 端口:587) 21cn.c ...
- ashx中session的使用
在平常的页面上是用是很容易就的到request,response对像,从而对其进行一些操作,但在ashx(一般处理程序)中却是有一点的不同, 在ashx你无法正常的使用session,即 contex ...
- ubuntu没有进入图形界面解决办法
可以通过设置runlevel 为2 来控制以后的登陆,或者是升级不完全.中间出错了,无法正常登陆.有2种方式来进入图形界面: 1. 登陆系统后,输入如下命令来启动图形界面: startx 2. 登陆系 ...
- 转载:牛魔王的世界观 »谈谈ie6不支持min-height与max-height的解决方法
转载网址:http://www.niumowang.org/html-css/ie6-min-height/ 手里的项目还在继续,今天正好遇到了min-height的问题,干脆在这里记录下来.我是喜欢 ...
- php base64数据与图片的转换
1.解析base64数据成图片 The problem is that data:image/bmp;base64, is included in the encoded contents. This ...
- iOS中3种正则表达式的使用与比较-备
1.利用NSPredicate(谓词)匹配 例如匹配有效邮箱: ? 1 2 3 4 NSString *email = @“nijino_saki@163.com”: NSString *regex ...
- spserver 开源服务器框架研究与分析
网上开源的C/C++服务器框架 还是比较少的. 最近研究了 spserver , 里面用了较多的设计模式,使用设计模式的目的是把不变的东西和可变的东西分离并且封装起来,避免以后修改代码, 应用设计模式 ...
- 非索引列上的统计 <第二篇>
非索引列上的统计 有时候,可能在连接或过滤条件中的列上没有索引.即使对这种非索引列,如果查询优化器知道这些列的数据分布(统计),它也很可能做出最佳的选择. 除了索引上的统计,SQL Server可以在 ...
- 深入浅出Node.js (4) - 异步编程
4.1 函数式编程 4.1.1 高阶函数 4.1.2 偏函数用法 4.2 异步编程的优势与难点 4.2.1 优势 4.2.2 难点 4.3 异步编程解决方案 4.3.1 事件发布/订阅模式 4.3.2 ...
- telnet 不是内部或外部 命令
win7->程序和功能->打开或关闭Windows功能->找到telnet安装下