`
hunxiejun
  • 浏览: 1137587 次
文章分类
社区版块
存档分类
最新评论

Object- C 内存管理之理解autorelease

 
阅读更多

转自:http://blog.sina.com.cn/s/blog_6853c0db0100mtqk.html


如果你能够真正的理解autorelease,那么你才是理解了Objective c的内存管理。Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的Autoreleasepool中,当该pool被释放时,该pool中的所有Object会被调用Release。

专题:iPhone应用程序开发初探

[1]在Iphone项目中,大家会看到一个默认的Autoreleasepool,程序开始时创建,程序退出时销毁,按照对Autorelease的理解,岂不是所有autoreleasepool里的对象在程序退出时才release, 这样跟内存泄露有什么区别?

答案是,对于每一个Runloop,系统会隐式创建一个Autoreleasepool,这样所有的releasepool会构成一个象CallStack一样的一个栈式结构,在每一个Runloop结束时,当前栈顶的Autoreleasepool会被销毁,这样这个pool里的每个Object会被release。

那什么是一个Runloop呢?一个UI事件,Timer call, delegate call,都会是一个新的Runloop。例子如下:


  1. NSString*<wbr>globalObject; <wbr></wbr></wbr>
  2. -<wbr>(</wbr>void)applicationDidFinishLaun<wbr>ching:(UIApplication<wbr>*)application<wbr><wbr></wbr></wbr></wbr></wbr>
  3. {<wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr>
  4. globalObject<wbr>=<wbr>[[NSString<wbr>alloc]<wbr>initWithFormat:@</wbr></wbr></wbr></wbr>"Test"]; <wbr></wbr>
  5. 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>
  6. [globalObject<wbr>retain]; <wbr></wbr></wbr>
  7. 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>
  8. } <wbr></wbr>
  9. -<wbr>(</wbr>void)applicationWillTerminate<wbr>:(UIApplication<wbr>*)application<wbr></wbr></wbr></wbr>
  10. { <wbr></wbr>
  11. 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>
  12. //<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>
  13. } <wbr></wbr>
  14. -(IBAction)onButtonClicked <wbr></wbr>
  15. { <wbr></wbr>
  16. [globalObject<wbr>autorelease]; <wbr></wbr></wbr>
  17. NSLog(@"Retain<wbr>count<wbr>after<wbr>autorelease:<wbr>%d"</wbr></wbr></wbr></wbr>,<wbr>[globalObject<wbr>retainCount]);<wbr><wbr></wbr></wbr></wbr></wbr>
  18. <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>
  19. }<wbr></wbr>

[2]为什么需要Auto release ?

2.1)很多C/C++转过来的程序员会说,这个auto release有什么好,象C/C++那样,自己申请,自己释放,完全可控不好么, 这个auto relase 完全不可控,你都不知到它什么时候会被真正的release。我的理解它有一个作用就是可以做到每个函数对自己申请的对象负责,自己申请,自己释放,该函数的调用者不需要关心它内部申请对象的管理。<wbr>在下面这个例子中,Func1的调用者不需要再去关心obj的释放。</wbr>


  1. ClassA<wbr>*Func1() <wbr></wbr></wbr>
  2. { <wbr></wbr>
  3. <wbr><wbr>ClassA<wbr>*obj<wbr>=<wbr>[[[ClassA<wbr>alloc]init]autorelease]; <wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  4. <wbr><wbr></wbr></wbr>return<wbr>obj; <wbr></wbr></wbr>
  5. }<wbr></wbr>

实际上对于 [NSString stringWithFormat:] 这类构造函数返回的对象都是autorelease的。

2.2) autorelease pool来避免频繁申请/释放内存(就是pool的作用了)。这个应该是相对比较好理解的。

总结:1)一定要注意Autoreleasepool的生存周期,理解Runloop,避免在对象被释放后使用。

2)[NSString stringWithFormat:]这类函数返回的对象是不需要再自己release的,它已经被autorelease了, 如果你想把它当一个全局对象使用,那必须自己再retain, 释放时再release。


分享到:
评论

相关推荐

    前端开源库-node-circleci-autorelease

    前端开源库-node-circleci-autorelease节点circleci autorelease,在circleci上创建释放标记

    object-c基础教程

    大纲  开始吧 ... 内存管理 o Retain and Release(保留与释放) o Dealloc o Autorelease Pool  Foundation Framework Classes o NSArray o NSDictionary  优点与缺点  更多信息

    02-内存管理1

    1&gt; 系统自带的绝大数类方法返回的对象,都是经过autorelease的4.block在ARC中和MRC中的用法有什么区别,需要注意什么1.对于没有引用外部变量

    Google Objective-C Style Guide 中文版

    Google Objective-C Style Guide 中文版 目录 例子 空格与格式 空格与制表符 行宽 方法声明与定义 方法调用 @public与@private 异常 协议 命名 文件名 Objective-C++ 类名 分类名 Objective-C方法名 变量名 注释 ...

    Objective-c对象组装XML

    [map setObject:@"c" forKey:@"content"]; 或者 NSMutableArray *list = [[NSMutableArray alloc]init]; NSMutableDictionary *map1 = [[NSMutableDictionary alloc]init]; [map1 setObject:@"a1" forKey:@...

    mulle-clang::ID_button:用于mulle-objc的Objective-C编译器

    mulle-clang 这是一个基于clang 10.0.0的Objective-C编译器,是为运行时编写的。 它对应于mulle-objc-runtime v0.17或更高版本。 有关的更多信息,请... 您不能执行显式的内存管理(如-dealloc , -autorelease ,

    IOS高级内存管理编程指南.pdf

    介绍IOS内存管理的一本电子书,初学者可以很快的了解ios上的内存管理的机制,有一定经验的也可以从中得到新的收获。

    Node.js-mysql-autoRelease:node.js mysql事务自动释放连接

    Node.js-mysql-autoRelease node.js mysql transaction Auto Release connection\ 实现Node.js中连接池自动回收连接功能

    Programming in Objective-C 4th Edition

    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的环境下,如何管理内存

    Objective-C学习之ARC的实现方法

    前言 在ARC出现以前,程序员们只能靠retain/relese/autorelease来确保对象们恰好“坚持”到被需要的那一刻。...ARC使内存管理在大部分时候变得如同小事一桩,但我们仍要在决定自己的类如何管理其它对象的引用

    Objective C Memory Management Essentials(PACKT,2015)

    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 ...

    详解iOS应用开发中的ARC内存管理方式

    ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain、release、autorelease语句。你不再需要担心内存管理,因为编译器为你处理了一切 注意:ARC 是编译器特性,...

    autorelease-github:通过 GitHub API 为您的构建管道自动发布

    autorelease-github 通过 GitHub API 为您的构建管道自动发布 这是一个非常简单的项目,它需要 N 个文件并使用 bash、curl 和 jq 通过上传它们。 它旨在成为构建管道中的嵌入式发布构建。 输入是一堆文件和一个放...

    objective-c-tutorial:这是我在学习时编写的所有目标c教程代码

    客观教学这是我在学习时编写的所有目标c教程代码#基本语法正常的printf操作NSlog示例autoRelease池示例#NSString操作NSString操作在这里NSRange示例NSMutableString示例#NSArray示例NSArray示例NSArray函数示例...

    AutoReleaseTool:自动部署桌面应用程序的CICD工具

    通过在完整的CI / CD管道配置中使用AutoRelease,为您的桌面应用程序创建新版本并将其部署到其用户所需的全部过程很简单: 将您的更改推送到定义的github版本分支触发一个webhook,该webhook将在 WM中启动构建过程...

    iPhone开发、ObjectiveC_面试题目

    self.name = “object”;和 name =”object” 有什么不同吗? 3、这段代码有什么问题吗: @implementation Person - (void)setAge:(int)newAge { self.age = newAge; } @end 4、什么是retain count? 5、...

    Auto Release Sh*t-crx插件

    语言:中文 (简体) 自动生成发版申请 它根据地址自动生成发版申请单,故名:auto-release-sh*t

    ios开发小技巧

    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消息时,会发生如下过程:

Global site tag (gtag.js) - Google Analytics