iOS-autorelease

直接看第四特点内容即可。

一、实现原理

主要是通过objc_autoreleasepoolpush、objc_autoreleasepoolpop、objc_autorelease这三个函数实现的。这三个函数其实是通过AutoreleasePoolPage 的push、pop、autorelease函数来实现的。每个AutoreleasepoolPage 实例对象的大小都是 4096 个字节。

  • push,生成AutoreleasePoolPage实例。
  • autorelease,相当于NSAutoreleasePool的addObject类方法,取得正在使用的poolPage实例,然后执行autoreleasePoolPage->add(obj)方法,我们可以理解为添加到内部数组中。
  • pop,销毁autoreleasePoolPage实例,并调用内部数组中所有对象的release方法。

自动释放池机制就像“栈”(stack)一样。系统创建好自动释放池之后,就将其通过推入栈中;在对象上执行自动释放操作,就相当于将其放入栈顶的那个池子当中;而清空自动释放池,则相当于将其从栈中弹出。
Autoreleasepool 是一个由 AutoreleasepoolPage 双向链表的结构,其中 child 指向它的子 page,parent 指向它的父 page:

双向链表

每个线程都有个AutoreleasePool栈,

二、ARC下的使用情况

1.@autoreleasepool{}来代替“NSAutoreleasePool类对象生成、持有以及废弃”。
2.__autoreleasing修饰符来代替“调用对象的autorelease方法”。

显式的附加__autoreleasing修饰符同显式的附加__strong修饰符一样罕见。
在arc中哪些地方隐式的用到了autorelease

  1. 取得非自己生成并持有的对象。如下代码,虽然可以使用alloc/new/copy/mutableCopy以外的方法来取得对象,但该对象已被注册到autoreleasepool。
id obj = [NSMutableArray array];

包括:

+ (id)array
{
    id obj = [[NSMutableArray alloc] init];
    return obj;
}

因为该对象作为函数的返回值,编译器会自动将其注册到autoreleasepool。

  1. 在访问附有__weak修饰符的变量时,实际上必定要访问到注册到autoreleasepool的对象。
id __weak ojb1 = obj0;
NSLog(@"%@",obj1);

实际相当于:

id __weak obj1 = obj0;
id __autorelasing tmp = obj1;
NSLog(@"%@",tmp);
  1. id的指针或对象的指针在没有显式指定时会被附加上__autoreleasing修饰符。
id *obj 和NSString **obj

实际上等同于

id __autoreleasing *obj 和NSString *__autoreleasing *obj

看如下的例子,比较好理解了:

//.h
- (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error
//.m
NSError *error = nil;
[[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];

解释:其实它和第一种情况一样,通过alloc/new/copy/mutableCopy方法以外取得的为:非自己生成并持有的对象,(之前为返回值,现在为参数都一样),因此也会注册到autoreleasepool中。

注:下边代码会报错

NSError *error = nil;
NSError **pError = &error;

因为,赋值给对象指针时,所有权符必须一致,改为如下即可:

NSError *__strong*pError = &error;

三、AutoreleasePool的创建

1. 线程中的AutoreleasePool

  • 主线程中,伴随每一个RunLoop的启动都会有默认的AutoreleasePool创建。


    AutoreleasePool在RunLoop中的创建

    下面我们来解释一下这张图:
    从程序启动到加载完成是一个完整的运行循环,然后会进入休眠,等待接收用户交互,用户的每一次交互都会再次启动运行循环,来处理用户的所有的触摸、点击事件。运行循环再次启动的时候会创建一个AutoreleasePool,来处理我们编写的代码处理事件,这些都执行完了的时候,RunLoop也就会结束,RunLoop即将结束时,会销毁AutoreleasePool。

  • 其他线程
    GCD机制中的线程,这些线程默认都有自动释放池。
    NSOperation,自定义的NSOperation类中的main方法中,需要手动创建AutoreleasePool,而blockOperationinvocationOperation不需要手动创建,系统已经帮我们封装好了。
    自定义的NSThread 需要手动创建自动释放池。

2. 手动创建的场景

什么时候需要手动创建呢?

  1. 循环中创建了大量的autorelease对象,利用@autoreleasepool优化循环, 降低内存峰值。
  2. 如果你的应用程序或者线程是要长期运行的并且有可能产生大量autoreleased对象, 你应该使用autorelease pool blocks。
  3. 长期在后台中运行的任务。

四、特点

  • 以栈为节点通过双向链表的形式组合而成
  • 与线程一一对应



    对应的push、pop是通过AutoreleasePoolPage的push和pop操作来完成。


    AutoreleasePoolPage

    其中,next指向当前栈可填充的位置。
    AutoreleasePoolPage::Push

当执行push操作时,会在next的位置置为nil(哨兵对象),然后next向下移动,对象依次加入到next的位置;

AutoreleasePoolPage::Pop

参考资料:
最后的使用场景参考了iOS中autorelease的那些事儿

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容