如果你使用过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的释放时机的更多相关文章

  1. 75. Autorelease机制及释放时机

    Autorelease机制是iOS开发人员管理对象内存的好伙伴.MRC中.调用[obj autorelease]来延迟内存的释放是一件简单自然的事:ARC下,我们甚至能够全然不知道Autoreleas ...

  2. Autorelease自动释放池的使用

    Autorelease自动释放池的使用 使用ARC开发,只是在编译时,编译器会根据代码结构自动添加了retain.release和autorelease. MRC内存管理原则:谁申请,谁释放 遇到al ...

  3. Unity3D中可中途释放的单例

    Unity3D中可中途释放的单例 使用静态类,静态变量的坏处是从程序加载后就一直占用内存,想要释放比较麻烦,可是之前使用的单例,没有提供释放的方法,那是不是也同静态的一样直到程序结束菜释放?那单例的好 ...

  4. 理解Objective C 中id

    什么是id,与void *的区别 id在Objective C中是一个类型,一个complier所认可的Objective C类型,跟void *是不一样的,比如一个 id userName, 和vo ...

  5. 浅谈Objective—C中的面向对象特性

    Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...

  6. Delphi中关于资源释放(Free,Relealse,FreeAndNil)

    根据日常编程经验,得出一些Delphi中关于资源释放的体会. 假如有对象Obj为TObject类型: 1) Obj.Free直接释放资源后,调用OnDestroy事件,但是没有将Obj指针值置为Nil ...

  7. iOS中控制器的释放问题

    iOS中控制器的释放问题 ARC工程是可以重写dealloc方法并被系统调用的,但不需要手动调用父类的dealloc,手写[super dealloc]方法会报错,事实上系统会自动帮你调用父类的dea ...

  8. Java中static块执行时机

    Java中static块执行时机 演示例子 在使用static进行初始化的操作,怎么也执行不了!代码如下: public class StaticDemo { public static final ...

  9. 如何在Qt资源文件中包含和释放exe等各种类型文件?

    操作系统:Windows 10 X64 企业版 Qt: 5.8.0 QtCreater: 4.2.1 刚刚开始学习Qt,不断遇到困难和挑战,前几天在各个QQ群里询问如何在Qt的资源文件中包含和释放ex ...

随机推荐

  1. Xcode 配置常用变量(SRCROOT, PROJECT_DIR, PROJECT_NAME)

    https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/ ...

  2. Chrome的隐身模式

    先来说说隐身模式的启用方法吧 1.键盘快捷:Ctrl + Shift + N. 2.在Windows7下的任务栏处,右击“Chrome”图标,会出一个下拉菜单,点击“新建隐身窗口”. 3.你还可以在一 ...

  3. [新]最近用unity5弄的一些渲染

    Unity Separable Bokeh Depth-of-Field Hexagonal Blur Unity3d Realtime Dynamic Clouds Rendering hemisp ...

  4. linux内核申请内存函数

    kmap函数:    把某块高端内存映射到页表,然后返回给用户一个填好vitual字段的page结构    建立永久地址映射,不是简单的返回virtual字段的pageioremap:    驱动程序 ...

  5. Java笔记(十八)……包

    概述 对类文件进行分类管理. 给类提供多层命名空间. 写在程序文件的第一行. 类名的全称的是 包名.类名. 包也是一种封装形式. 访问权限 引用<The Complete Reference&g ...

  6. HDOJ-ACM1005(JAVA)

    转载声明:原文转自http://www.cnblogs.com/xiezie/p/5502918.html JAVA语言实现: 拿到题目第一反应是简单地实现递归: import java.util.* ...

  7. Codeforces4D - Mysterious Present(LIS)

    题目大意 给你一张宽为w,长为h的的贺卡,然后给你n个信封,每个信封宽为wi,长为hi,问你最多能在贺卡上嵌套多少个信封,如果某个信封i如果能够装在信封j里,当且仅当w[i]<w[j]& ...

  8. .NET版本问题 转[.Net Framework Initialization Error – Unable to find a version of the runtime to run this applicatio]

    转自:http://blog.csdn.net/rrrrssss00/article/details/7069009 dev注册程序问题部署一个VS2010开发的程序时遇到 了一个非常奇怪的问题,客户 ...

  9. Laravel教程:laravel 4安装及入门

    一.安装Composer首先你需要安装Composer,Composer是PHP依赖管理工具,Laravel框架就是使用 Composer 执行安装和依赖管理. 注:(1)若安装Composer出错, ...

  10. [转]JQuery判断浏览器类型版本1.9和2.0之后的区别

    转至:http://zhidao.baidu.com/link?url=Nzk2aSxBKRZKYg9Evqn8hLwMyXTI-4jza-zCAZq4Vd6hWCOHIvuBX6yj8hzDYDrf ...