理解Autorelease pool

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

[1]在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。

时间: 2024-11-05 23:29:29

理解Autorelease pool的相关文章

Autorelease Pool

现在已经是 ARC 时代了,但是了解更多的 Objective-C 的内存管理机制仍然是十分必要的.一直以来我都弄不清楚 autorelease 的原理,后面看了很多资料,才慢慢了解到 autorelease 的原理. - (void)test { NSString *string = [NSString stringWithFormat:@"liuluoxing"]; NSString *string_weak_ = string; } 下面我们来捋一捋这个变量的内存引用计数的变化:

Objective-C Autorelease Pool 的实现原理

内存管理一直是学习 Objective-C 的重点和难点之一,尽管现在已经是 ARC 时代了,但是了解 Objective-C 的内存管理机制仍然是十分必要的.其中,弄清楚 autorelease 的原理更是重中之重,只有理解了 autorelease 的原理,我们才算是真正了解了 Objective-C 的内存管理机制.注:本文使用的 runtime 源码是当前的最新版本 objc4-646.tar.gz . autoreleased 对象什么时候释放 autorelease 本质上就是延迟调

objective-C 的内存管理之-自动释放池(autorelease pool)

如果一个对象的生命周期显而易见,很容易就知道什么时候该new一个对象,什么时候不再需要使用,这种情况下,直接用手动的retain和release来判定其生死足矣.但是有些时候,想知道某个对象在什么时候不再使用并不那么容易.如果下面的代码,看上去非常简单: Sample.h类接口部分 #import @interface Sample : NSObject { } -(NSString*) toString; @end Sample.m 类实现部分 #import "Sample.h"

Objective-C Autorelease Pool 的实现原理[转]

http://blog.leichunfeng.com/blog/2015/05/31/objective-c-autorelease-pool-implementation-principle/ 内存管理一直是学习 Objective-C 的重点和难点之一,尽管现在已经是 ARC 时代了,但是了解 Objective-C 的内存管理机制仍然是十分必要的.其中,弄清楚 autorelease 的原理更是重中之重,只有理解了 autorelease 的原理,我们才算是真正了解了 Objective

Using Autorelease Pool Blocks

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-CJBFBEDI Using Autorelease Pool Blocks Autorelease pool blocks provide a mechanism whereby you can rel

理解Shared Pool 2

Shared Pool的Sub Pool技术 由于硬解析时需要从Shared Pool重分配内存(分配内存是需要持有Shared Pool Latch),所以在硬解析比较多的系统中,非常容易引起Shared Pool Latch的征用.为了减缓该Latch的征用,从Oracle 9i开始,共享池可分为多个子池(Sub Pool)来管理(最多7个),下一节将主要讲解Shared Pool的Sub Pool技术. Sub Pool数量受以下几个因素的影响: 系统CPU的数量.默认情况下,在Oracl

理解Shared Pool 1

堆管理 shared pool是利用堆内存管理方式管理的(KGH:Kernel Generic Heap).从Oracle 9i开始,可以有多个最高级堆(TOP-LEVEL HEAP),最高级堆可以分为多个副堆,副堆下面还拥有下属副堆.堆和副堆的结构基本相同.从物理上来看,一个堆由于多个内存区以LINKED LIST的形式连接组成.一个内存区物理上使用一个GRANULE,一个内存区有多个CHUNK组成,所以CHUNK是HEAP的最小内存单位.CHUNK的使用情况可以通过X$KSMSP内部视图查看

再次理解autorelease对象

一般通过函数返回值返回的对象都是autorelease对象(包括直接通过返回值返回的和通过指针的指针返回的),MRC下需要自己retain这个对象.autorelease的对象会在当前autoreleasepool进行drain操作的时候被发送release消息.但是以init.new.copy.mutableCopy开头的函数生成的对象引用计数默认就是1,所以MRC下用这些方法创建对象时不需要自己另外retain这个对象. 原文地址:https://www.cnblogs.com/yibinp

组长问我几天能开发一个人见人爱的百万量级Android相机,我是这样回答的...

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由QQ空间开发团队发表于云+社区专栏 最近我负责开发了一个跟Android相机有关的需求,新功能允许用户使用手机摄像头,快速拍摄特定尺寸(1:1或3:4)的照片,并支持在拍摄出的照片上做贴纸相关的操作.由于之前没有接触过Android相机开发,所以在整个开发过程中踩了不少坑,费了不少时间和精力.这篇文章总结了Android相机开发的相关知识.流程,以及容易遇到的坑,希望能帮助今后可能会接触Android相机开发的朋友快速上手,节省时