Objective-c中autorelease的释放时机
如果你使用过MRR,autorelease这个关键字应该是太熟悉了,每次在我们生成一个新的对象返回时,都需要向这个对象发送autorelease消息,目的是为了延时释放创建的对象。那到底是在什么时候,这个对象会被释放呢?有什么方法可以更快的释放一个autorelease对象呢?
咱们先来看一个现象:
@property (weak, nonatomic) NSString *weakString;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSString *hello = [[NSString alloc] initWithCString:"it will be released at the end of current runloop" encoding:NSUTF8StringEncoding];
self.weakString = hello;
NSLog(@"%@ - %@", self.weakString, NSStringFromSelector(_cmd));
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(@"%@ - %@", self.weakString, NSStringFromSelector(_cmd));
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(@"%@ - %@", self.weakString, NSStringFromSelector(_cmd));
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"-2--%@ - %@", self.weakString, NSStringFromSelector(_cmd));
});
}
我们创建了一个viewDidLoad方法中创建了一个weak指针指向一个字符串,当代码执行到viewWillAppear:和viewDidAppear:时,我们依然可以打印出weak指针指向的字符串,当在viewDidAppear:中在下一个runloop中执行打印操作时,weak指针就指向nil了,why ?
编译器在ARC环境下可能会帮我们把这条语句self.weakString = hello改成类似这样:
self.weakString = [[hello retain] autorelease];
当向hello发送autorelease消息时,hello将会被加入到当前的autorelease pool中,当autorelease pool release时,它会像pool中hello发送release消息,然后hello就被真正释放了。
可是看看我们的示例代码,我们并没有autorelease pool啊,我们知道app启动时main函数里面有一个autorelease pool,难道是这个autorelease pool被释放了? 显然不可能,那可以肯定的说,系统隐式的帮我们创建了autorelease pool。
系统怎么知道我们要为我们创建autorelease pool的呢?
main函数启动后系统会创建一个main runloop,每个runloop系统都会分配一个autorelease pool,它将在app退出的时候释放app所占用的内存。当用户输入设备(如点击button、键盘按下)、网络链接(socket收到数据)、定期或时间延迟事件(NSTimer),还有异步回调(NSURLConnection的异步请求)等三类(sources、timers、observers)会将这个main runloop激活并产生一个autorelease pool,当runloop进入睡眠时,释放这个autorelease pool。
比如我们的demo里面,是一个cell点事件触发了一个页面切换,从点击cell点击激活runloop到新页面的viewDidAppear:结束后runloop进入休眠,这中间创建的autorelease pool就是那个把weakString释放的家伙。
参考资料:
1)http://www.cnblogs.com/whyandinside/p/3489951.html
2)https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html
Objective-c中autorelease的释放时机的更多相关文章
- 75. Autorelease机制及释放时机
Autorelease机制是iOS开发人员管理对象内存的好伙伴.MRC中.调用[obj autorelease]来延迟内存的释放是一件简单自然的事:ARC下,我们甚至能够全然不知道Autoreleas ...
- Autorelease自动释放池的使用
Autorelease自动释放池的使用 使用ARC开发,只是在编译时,编译器会根据代码结构自动添加了retain.release和autorelease. MRC内存管理原则:谁申请,谁释放 遇到al ...
- Unity3D中可中途释放的单例
Unity3D中可中途释放的单例 使用静态类,静态变量的坏处是从程序加载后就一直占用内存,想要释放比较麻烦,可是之前使用的单例,没有提供释放的方法,那是不是也同静态的一样直到程序结束菜释放?那单例的好 ...
- 理解Objective C 中id
什么是id,与void *的区别 id在Objective C中是一个类型,一个complier所认可的Objective C类型,跟void *是不一样的,比如一个 id userName, 和vo ...
- 浅谈Objective—C中的面向对象特性
Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...
- Delphi中关于资源释放(Free,Relealse,FreeAndNil)
根据日常编程经验,得出一些Delphi中关于资源释放的体会. 假如有对象Obj为TObject类型: 1) Obj.Free直接释放资源后,调用OnDestroy事件,但是没有将Obj指针值置为Nil ...
- iOS中控制器的释放问题
iOS中控制器的释放问题 ARC工程是可以重写dealloc方法并被系统调用的,但不需要手动调用父类的dealloc,手写[super dealloc]方法会报错,事实上系统会自动帮你调用父类的dea ...
- Java中static块执行时机
Java中static块执行时机 演示例子 在使用static进行初始化的操作,怎么也执行不了!代码如下: public class StaticDemo { public static final ...
- 如何在Qt资源文件中包含和释放exe等各种类型文件?
操作系统:Windows 10 X64 企业版 Qt: 5.8.0 QtCreater: 4.2.1 刚刚开始学习Qt,不断遇到困难和挑战,前几天在各个QQ群里询问如何在Qt的资源文件中包含和释放ex ...
随机推荐
- NOI2014 魔法森林
3669: [Noi2014]魔法森林 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 106 Solved: 62[Submit][Status] ...
- POJ2236 Wireless Network 并查集
水题 #include<cstdio> #include<cstring> #include<queue> #include<set> #include ...
- HDU 1285
#include<stdio.h> #include<string.h> int degree[505],vis[505],map[501][501]; int main() ...
- Bootstrap基本使用[转]
Bootstrap是Twitter推出的一个由动态CSS语言Less写成的开源CSS/HTML框架(同时提供Sass 移植版代码).Bootstrap提供了全面的基本及组件样式并自带了13个jQuer ...
- Mathtype常用快捷键
1. 打开/关闭MathType窗口 alt+ctrl+q:插入inline公式 可在word中设置快捷键,直接调用公式编辑器,工具--〉自定义--〉键盘,选择 插入--insertequation ...
- Unity3d 粒子工具注释
今天群里有人问到瀑布粒子如何调整尺寸. 我查到ellipsoid可以调节产生粒子的空间范围,然后还需要调节粒子的长度.他那个瀑布太长了.max energy和min energy这两个参数可以用来控制 ...
- Java笔记(十三)……面向对象III继承(inheritance)
继承概述 继承概述 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继那个类即可. 多个类可以称为子类,单独这个类称为父类或者超类. 子类可以直接访 ...
- [E120L][KitKat][4.4.2][CM11] CM11 rom+ google app安装心得
1. 本文针对 三星手机型号: E120L 即 samsung galaxy S2 HD LTE 2. 本文安装的android ROM 的内核为4.4.2 KitKat 3. 本文安装的第三方RO ...
- 【Java基础】Java内部类
什么是内部类 把类定义在其他类的内部,这个类就被称为内部类. 内部类的分类 内部类分为两种,分别为成员内部类和局部内部类: 成员内部类:和成员变量和成员方法定义在同级 局部内部类:和局部变量定义在同级 ...
- POJ2478 - Farey Sequence(法雷级数&&欧拉函数)
题目大意 直接看原文吧.... The Farey Sequence Fn for any integer n with n >= 2 is the set of irreducible rat ...