iOS-@autoreleasepool-内存的分配与释放
2016-01-26 17:34
417 查看
前言
开发过iOS、Mac的朋友应该对“@autoreleasepool”不陌生。只要在Xcode里创建一个工程,就能看到下面这样的代码://iOS program int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } //Command line program int main(int argc, const char *argv[]) { @autoreleasepool { //... } return 0; }
看,每个main函数的主体都被@autoreleasepool的Block块包在里面,也就是说,接下来所有的对象创建都在这个block里面。
那么,@autoreleasepool的作用到底是什么呢?我们开发中可以用它来做什么呢?
可以在某些情况下,大幅度降低程序的内存占用,如下图:
测试的内容:500000次循环,每次循环创建一个NSNumber实例和两个NSString实例。
图:红线表示没有用@autoreleasepool时的内存占用。
图:绿线表示用了@autoreleasepool优化后的内存占用!
效果是不是很明显!
代码Github地址:AutoReleasePoolTestExample Xcode
6, iOS 8, iPhone 5模拟器.
MRC 与 ARC
MRC(Mannul Reference Counting)和ARC(Automatic Reference Counting),分别对应着手动引用计数和自动引用计数。对!是计数,不是“GC、垃圾回收”什么的,就是说,在Objective-C的开发中,ARC不代表像Java那样有GC做垃圾回收,所以本质上还是要“手动”管理内存的。也就是说,我们在ARC环境下写的代码,不用自己手动插入“retain、release这些消息”,ARC会在编译时为我们在合适的位置插入,释放不必要的内存。
而@autoreleasepool就跟对象的release密切相关。
@autoreleasepool 干了啥
在MRC时代,如果我们想先retain一个对象,但是并不知道在什么时候可以release它,我们可以像下面这么做:NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString* str = [[[NSString alloc] initWithString:@"tutuge"] autorelease]; //use str... [pool release]; //str is released
就是说,我们可以在创建对象的时候给对象发送“autorelease”消息,然后当NSAutoreleasePool结束的时候,“标记过”autorelease的对象都会被“release”掉,也就是会被释放掉。
但是在ARC时代,我们不用手动发送autorelease消息,ARC会自动帮我们加。而这个时候,@autoreleasepool做的事情,跟NSAutoreleasePool就一模一样了。
什么时候用@autoreleasepool
根据Apple的文档,使用场景如下:写基于命令行的的程序时,就是没有UI框架,如AppKit等Cocoa框架时。
写循环,循环里面包含了大量临时创建的对象。(本文的例子)
创建了新的线程。(非Cocoa程序创建线程时才需要)
长时间在后台运行的任务。
利用@autoreleasepool优化循环
利用@autoreleasepool优化循环的内存占用,我觉得最有用的一点,下面就说说这个点。如下面的循环,次数非常多,而且循环体里面的对象都是临时创建使用的,就可以用@autoreleasepool包起来,让每次循环结束时,可以及时的释放临时对象的内存。
//来自Apple文档,见参考 NSArray *urls = <# An array of file URLs #>; for (NSURL *url in urls) { @autoreleasepool { NSError *error; NSString *fileContents = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error]; /* Process the string, creating and autoreleasing more objects. */ } }
这么做的效果是极其显著地,就如本文最开始的图一样,可以自己把示例工程下回来运行下试试~
总结
@autoreleasepool看起来很不“起眼”,平常开发很容易就忽略它了,但是仔细一看,确如此有用~本文转自土土哥:http://tutuge.me/2015/03/17/what-is-autoreleasepool/
相关文章推荐
- iOS_导入libxml2.2框架后,找不到<libxml/tree.h>的解决办法
- iOS开发,图片制作水印,图片裁剪,图片条纹背景,图片截图,以及将图片成文件存储。基于Quartz2D技术
- termios结构体
- iOS-开发项目的项目目录整理
- iOS BSD socket编程
- CALayer Mask - 1
- iOS---Foundation(NSURLCache.h)简介
- iOS调用系统相册,相机上传头像的基本技巧
- 进击的KFC:IOS开发之格式化日期时间
- iOS性能优化
- IOS监听屏幕状态
- 基础类的DSP/BIOS API调用
- iOS 大学列表检索
- iOS 高效开发-正确的使用枚举(Enum)
- iOS开发系列--视图切换
- iOS崩溃调试的使用和技巧总结
- 使用Xcode和Instruments调试解决iOS内存泄露
- iOS常用正则表达式验证(手机号、密码格式、身份证号等)
- iOS 使用可变参数va_list, 定义一个方法
- ios正则表达式