文档章节

关于autorelease pool一个较好的理解

lightUp
 lightUp
发布于 2015/06/17 17:36
字数 689
阅读 14
收藏 0


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

 

[1]理解autoreleasepool

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

答案是,对于每一个Runloop系统会隐式创建一个Autorelease pool,这样所有的release pool会构成一个象CallStack一样的一个栈式结构,在每一个Runloop结束时,当前栈顶的Autorelease pool会被销毁,这样这个pool里的每个Object会被release。
那什么是一个Runloop呢? 一个UI事件,Timer call, delegate call, 都会是一个新的Runloop。Autorelease是保证一个method安全的,对于method中的函数调用也适用。例子如下:

NSString* globalObject;

- (void)applicationDidFinishLaunching:(UIApplication *)application
{
    globalObject = [[NSString alloc] initWithFormat:@"Test"];
    NSLog(@"Retain count after create: %d", [globalObject retainCount]); // output 1.
    [globalObject retain];
    NSLog(@"Retain count after retain: %d", [globalObject retainCount]); // output 2.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    NSLog(@"Retain count after Button click runloop finished: %d", [globalObject retainCount]);
    // 输出1. Button click loop finished, it's autorelease pool released, globalObject get released once.
}

-(IBAction)onButtonClicked
{
    [globalObject autorelease];
    NSLog(@"Retain count after autorelease: %d", [globalObject retainCount]);
    // 输出2。 Autorelease被call, globalObject被加如当前的AutoreleaePool。
}



[2]为什么需要Auto release ?


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

ClassA *Func1()
{
    ClassA *obj = [[[ClassA alloc]init]autorelease];
    return obj;
}


 

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


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


总结:

1)一定要注意Autorelease pool的生存周期,理解Runloop,避免在对象被释放后使用。
2)[NSString stringWithFormat:]这类函数返回的对象是不需要再自己release的,它已经被autorelease了, 如果你想把它当一个全局对象使用,那必须自己再retain, 释放时再release。


本文转载自:http://blog.sina.com.cn/s/blog_8c87ba3b0100tgfs.html

共有 人打赏支持
lightUp
粉丝 10
博文 242
码字总数 287936
作品 0
杭州
程序员
私信 提问
关于autorelease和release的理解

1.如果能够真正的理解autorelease,那么才是理解了Objective c的内存管理。Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的Autorel...

张志浩
2013/02/06
0
0
NSAutoReleasePool 讲解

好记性不如烂博客. 今天需要记录的是关于NSAutoReleasePool的理解.(大部分内容来自于iOS4.3 Library) Cocoa的内存管理主要依赖于Reference Counting, 而NSAutoReleasePool就是用来支持它的....

孙启超
2012/05/28
0
1
iPhone/Mac Objective-C内存管理教程和原理剖析

版权声明 此文版权归作者Vince Yuan (vince.yuan#gmail.com)所有。欢迎非营利性转载,转载时必须包含原始链接http://vinceyuan.cnblogs.com/,且必须包含此版权声明的完整内容。 版本 1.1 发...

黑衣李白
2012/12/27
0
0
iPhone/Mac Objective-C内存管理教程和原理剖析 【一、基本原理】

前言 初学objectice-C的朋友都有一个困惑,总觉得对objective-C的内存管理机制琢磨不透,程序经常内存泄漏或莫名其妙的崩溃。我在这里总结了自己对objective-C内存管理机制的研究成果和经验,...

长平狐
2012/10/25
46
0
objective - c 内存管理机制

版权声明 此文版权归作者VinceYuan (vince.yuan#gmail.com)所有。欢迎非营利性转载,转载时必须包含原始链接http://vinceyuan.cnblogs.com/,且必须包含此版权声明的完整内容。 版本1.1 发表...

雾灵峰
2012/11/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

想买的书

Java并发编程之美

miaojiangmin
3分钟前
1
0
Linux(centos7)共享文件

安装samba samba安装 关闭防火墙和selinux firewalld /etc/selinux/config SELINUX=enforcing改为SELINUX=disabled yum install -y samba samba-client systemctl start smb smbpasswd -a 用......

qinjiudong
4分钟前
1
0
SparkLauncher执行spark程序一直阻塞卡在running-undefined的情况处理

使用SparkLauncher提交spark程序时,有时间会一直卡在status是running状态 finalstatus为undefined,这种情况是因为使用的java的ProcessBuilder,查阅了资料后发现可能是因为buffer被填满,导...

那年的暖风
8分钟前
1
0
php中echo(),print(),print_r(),var_dump()与var_export()间的区别

echo()函数:输出一个或多个字符串。 输出所有参数。不会换行。 echo 不是一个函数(它是一个语言结构), 因此你不一定要使用小括号来指明参数,单引号,双引号都可以。 echo (不像其他语言...

hansonwong
9分钟前
0
0
php 生成 桌面快捷链接

<?php $Shortcut = "[InternetShortcut] URL=http://IP地址或网址IDList= [{000214A0-0000-0000-C000-000000000046}] Prop3=19,2 "; Header("Content-type: application......

zxcgzq
9分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部