转自:http://blog.sina.com.cn/s/blog_6853c0db0100mtqk.html
如果你能够真正的理解autorelease,那么你才是理解了Objective c的内存管理。Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的Autoreleasepool中,当该pool被释放时,该pool中的所有Object会被调用Release。
[1]在Iphone项目中,大家会看到一个默认的Autoreleasepool,程序开始时创建,程序退出时销毁,按照对Autorelease的理解,岂不是所有autoreleasepool里的对象在程序退出时才release, 这样跟内存泄露有什么区别?
答案是,对于每一个Runloop,系统会隐式创建一个Autoreleasepool,这样所有的releasepool会构成一个象CallStack一样的一个栈式结构,在每一个Runloop结束时,当前栈顶的Autoreleasepool会被销毁,这样这个pool里的每个Object会被release。
那什么是一个Runloop呢?一个UI事件,Timer call, delegate call,都会是一个新的Runloop。例子如下:
-
NSString*<wbr>globalObject;
<wbr></wbr></wbr>
-
-<wbr>(</wbr>void)applicationDidFinishLaun<wbr>ching:(UIApplication<wbr>*)application<wbr><wbr></wbr></wbr></wbr></wbr>
-
{<wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr>
-
globalObject<wbr>=<wbr>[[NSString<wbr>alloc]<wbr>initWithFormat:@</wbr></wbr></wbr></wbr>"Test"];
<wbr></wbr>
-
NSLog(@"Retain<wbr>count<wbr>after<wbr>create:<wbr>%d"</wbr></wbr></wbr></wbr>,<wbr>[globalObject<wbr>retainCount]);<wbr></wbr></wbr></wbr>//<wbr>output<wbr>1.</wbr></wbr><wbr></wbr>
-
[globalObject<wbr>retain];
<wbr></wbr></wbr>
-
NSLog(@"Retain<wbr>count<wbr>after<wbr>retain:<wbr>%d"</wbr></wbr></wbr></wbr>,<wbr>[globalObject<wbr>retainCount]);<wbr></wbr></wbr></wbr>//<wbr>output<wbr>2.</wbr></wbr><wbr></wbr>
-
}
<wbr></wbr>
-
-<wbr>(</wbr>void)applicationWillTerminate<wbr>:(UIApplication<wbr>*)application<wbr></wbr></wbr></wbr>
-
{
<wbr></wbr>
-
NSLog(@"Retain<wbr>count<wbr>after<wbr>Button<wbr>click<wbr>runloop<wbr>finished:<wbr>%d"</wbr></wbr></wbr></wbr></wbr></wbr></wbr>,<wbr>[globalObject<wbr>retainCount]);<wbr><wbr></wbr></wbr></wbr></wbr>
-
//<wbr>输出1.<wbr>Button<wbr>click<wbr>loop<wbr>finished,<wbr>it's<wbr>autorelease<wbr>pool<wbr>released,<wbr>globalObject<wbr>get<wbr>released<wbr>once.</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr><wbr></wbr>
-
}
<wbr></wbr>
-
-(IBAction)onButtonClicked
<wbr></wbr>
-
{
<wbr></wbr>
-
[globalObject<wbr>autorelease];
<wbr></wbr></wbr>
-
NSLog(@"Retain<wbr>count<wbr>after<wbr>autorelease:<wbr>%d"</wbr></wbr></wbr></wbr>,<wbr>[globalObject<wbr>retainCount]);<wbr><wbr></wbr></wbr></wbr></wbr>
-
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>//<wbr>输出2。<wbr>Autorelease被call,<wbr>globalObject被加如当前的AutoreleaePool。<wbr></wbr></wbr></wbr></wbr><wbr></wbr>
-
}<wbr></wbr>
[2]为什么需要Auto release ?
2.1)很多C/C++转过来的程序员会说,这个auto release有什么好,象C/C++那样,自己申请,自己释放,完全可控不好么, 这个auto relase 完全不可控,你都不知到它什么时候会被真正的release。我的理解它有一个作用就是可以做到每个函数对自己申请的对象负责,自己申请,自己释放,该函数的调用者不需要关心它内部申请对象的管理。<wbr>在下面这个例子中,Func1的调用者不需要再去关心obj的释放。</wbr>
-
ClassA<wbr>*Func1()
<wbr></wbr></wbr>
-
{
<wbr></wbr>
-
<wbr><wbr>ClassA<wbr>*obj<wbr>=<wbr>[[[ClassA<wbr>alloc]init]autorelease];
<wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
-
<wbr><wbr></wbr></wbr>return<wbr>obj;
<wbr></wbr></wbr>
-
}<wbr></wbr>
实际上对于 [NSString stringWithFormat:] 这类构造函数返回的对象都是autorelease的。
2.2) autorelease pool来避免频繁申请/释放内存(就是pool的作用了)。这个应该是相对比较好理解的。
总结:1)一定要注意Autoreleasepool的生存周期,理解Runloop,避免在对象被释放后使用。
2)[NSString stringWithFormat:]这类函数返回的对象是不需要再自己release的,它已经被autorelease了, 如果你想把它当一个全局对象使用,那必须自己再retain, 释放时再release。
分享到:
相关推荐
前端开源库-node-circleci-autorelease节点circleci autorelease,在circleci上创建释放标记
大纲 开始吧 ... 内存管理 o Retain and Release(保留与释放) o Dealloc o Autorelease Pool Foundation Framework Classes o NSArray o NSDictionary 优点与缺点 更多信息
1> 系统自带的绝大数类方法返回的对象,都是经过autorelease的4.block在ARC中和MRC中的用法有什么区别,需要注意什么1.对于没有引用外部变量
Google Objective-C Style Guide 中文版 目录 例子 空格与格式 空格与制表符 行宽 方法声明与定义 方法调用 @public与@private 异常 协议 命名 文件名 Objective-C++ 类名 分类名 Objective-C方法名 变量名 注释 ...
[map setObject:@"c" forKey:@"content"]; 或者 NSMutableArray *list = [[NSMutableArray alloc]init]; NSMutableDictionary *map1 = [[NSMutableDictionary alloc]init]; [map1 setObject:@"a1" forKey:@...
mulle-clang 这是一个基于clang 10.0.0的Objective-C编译器,是为运行时编写的。 它对应于mulle-objc-runtime v0.17或更高版本。 有关的更多信息,请... 您不能执行显式的内存管理(如-dealloc , -autorelease ,
介绍IOS内存管理的一本电子书,初学者可以很快的了解ios上的内存管理的机制,有一定经验的也可以从中得到新的收获。
Node.js-mysql-autoRelease node.js mysql transaction Auto Release connection\ 实现Node.js中连接池自动回收连接功能
Object References and the Autorelease Pool 403 The Event Loop and Memory Allocation 405 Summary of Manual Memory Management Rules 407 Automatic Reference Counting (ARC) 408 Strong Variables 408 Weak ...
这是一个简单的内存管理的示例,在非ARC的环境下,如何管理内存
前言 在ARC出现以前,程序员们只能靠retain/relese/autorelease来确保对象们恰好“坚持”到被需要的那一刻。...ARC使内存管理在大部分时候变得如同小事一桩,但我们仍要在决定自己的类如何管理其它对象的引用
You will begin with a basic understanding of memory management, and why memory leaks occur in an application, moving on to autorelease pools and object creation/storage to get an idea of how memory ...
ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain、release、autorelease语句。你不再需要担心内存管理,因为编译器为你处理了一切 注意:ARC 是编译器特性,...
autorelease-github 通过 GitHub API 为您的构建管道自动发布 这是一个非常简单的项目,它需要 N 个文件并使用 bash、curl 和 jq 通过上传它们。 它旨在成为构建管道中的嵌入式发布构建。 输入是一堆文件和一个放...
客观教学这是我在学习时编写的所有目标c教程代码#基本语法正常的printf操作NSlog示例autoRelease池示例#NSString操作NSString操作在这里NSRange示例NSMutableString示例#NSArray示例NSArray示例NSArray函数示例...
通过在完整的CI / CD管道配置中使用AutoRelease,为您的桌面应用程序创建新版本并将其部署到其用户所需的全部过程很简单: 将您的更改推送到定义的github版本分支触发一个webhook,该webhook将在 WM中启动构建过程...
self.name = “object”;和 name =”object” 有什么不同吗? 3、这段代码有什么问题吗: @implementation Person - (void)setAge:(int)newAge { self.age = newAge; } @end 4、什么是retain count? 5、...
语言:中文 (简体) 自动生成发版申请 它根据地址自动生成发版申请单,故名:auto-release-sh*t
iOS开发之UIlabel多行文字自动换行 (自动折行) UIView *footerView = [[UIView alloc]initWithFrame:CGRectMake(10, 100, 300, 180)]; UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(10, 100, 300, ...
我们需要先创建一个auto release pool,才能有效地实现autorelease机制,否则会导致内存泄露。当一个对象obj发送autorelease消息时,会发生如下过程: