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 ...
随机推荐
- [Mac] 使用Mac时的一些技巧
这篇博客就用来记录自己在使用Mac时学来的一些技巧吧! 1. 如何开启 Sticky key (在屏幕上显示输入的控制键) 就是这个东西啦,就是在视频演示的时候让别人看到自己按了什么控制键. 在s ...
- liunx下安装mysql没有初始密码的解决方法
#/etc/init.d/mysql stop #cd /usr/local/mysql #mysqld_safe --user=mysql --skip-grant-tables --skip-ne ...
- JSONP有什么作用
1.解决跨域访问数据 由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名.协议.端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求 ...
- [GitPython]使用python管理你的git库
你想使用python来自动管理一个git仓库的时候,GitPython是一个不错的选择. 简介: 先看看下面这段代码: from git import Repo repo = Repo("~ ...
- JDK PATH 和 CLASSPATH环境变量的作用及其配置
(1)PATH环境变量的作用 在安装JDK程序之后,在安装目录下的bin目录中会提供一些开发Java程序时必备的工具程序. 对于Java的初学者,建议在命令符模式下使用这些工具程序编译运行Java程序 ...
- grok 添加字段
filter { grok { match =>[ "message","%{IPORHOST:clientip} \[%{HTTPDATE:time}\] \&q ...
- spring框架源码编译
程序猿小菜一枚,最近从github上面下载下来一份spring各个项目的源码一份,但是弄了很长时间,因为网速和(fanqiang)的速度,希望大家不要再为这种无谓的时间花费时间,简单来说github上 ...
- QString转换为char*
QString在Qt里相当于C++里的std::string,或者是C里的c style string.不过,QString跟编码相关,在低层想把一个QString发送出去相当麻烦,尤其对方用的不是Q ...
- Python多进程(multiprocessing)
Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊.普通的函数调用,调用一次,返回一次,但是fork()调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为 ...
- 01串(dp)
01串 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 ACM的zyc在研究01串,他知道某一01串的长度,但他想知道不含有“11”子串的这种长度的01串共有多少个, ...