初学Objective-C的朋友都有一个困惑,总觉得对Objective-C的内存管理机制琢磨不透,程 序经常内存泄漏或莫名其妙的崩溃。我在这里总结了自己对Objective-C内存管理机制的研究成果和经验,写了这么一个由浅入深的教程。希望对大家有 所帮助,也欢迎大家一起探讨。

系统自动创建新的autorelease pool

在生成新的Run Loop的时候,系统会自动创建新的autorelease pool(非常感谢网友hhyytt和neogui的提醒)。注意,此处不同于xcode在新建项目时自动生成的代码中加入的autorelease pool,xcode生成的代码可以被删除,但系统自动创建的新的autorelease pool是无法删除的(对于无Garbage Collection的环境来说)。Objective-C没有给出实现代码,官方文档也没有说明,但我们可以通过小程序来证明。

在这个小程序中,我们先生成了一个autorelease pool,然后生成一个autorelease的ClassA的实例,再在一个新的run loop中生成一个autorelease的ClassB的对象(注意,我们并没有手动在新run loop中生成autorelease pool)。精简的示例代码如下,详细代码请见附件中的memman-run-loop-with-pool.m。

  1. int main(int argc, char**argv)
  2. {
  3. NSLog(@"create an autorelasePool\n");
  4. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  5. NSLog(@"create an instance of ClassA and autorelease\n");
  6. ClassA *obj1 = [[[ClassA alloc] init] autorelease];
  7. NSDate *now = [[NSDate alloc] init];
  8. NSTimer *timer = [[NSTimer alloc] initWithFireDate:now
  9. interval:0.0
  10. target:obj1
  11. selector:@selector(createClassB)
  12. userInfo:nil
  13. repeats:NO];
  14. NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
  15. [runLoop addTimer:timer forMode:NSDefaultRunLoopMode];
  16. [timer release];
  17. [now release];
  18. [runLoop run]; //在新loop中调用一函数,生成ClassB的autorelease实例
  19. NSLog(@"releasing autorelasePool\n");
  20. [pool release];
  21. NSLog(@"autorelasePool is released\n");
  22. return 0;
  23. }

输出如下:

create an autorelasePool

create an instance of ClassA and autorelease

create an instance of ClassB and autorelease

ClassB destroyed

releasing autorelasePool

ClassA destroyed

autorelasePool is released

注意在我们销毁autorelease pool之前,ClassB的autorelease实例就已经被销毁了。

有人可能会说,这并不能说明新的run loop自动生成了一个新的autorelease pool,说不定还只是用了老的autorelease pool,只不过后来drain了一次而已。我们可以在main函数中不生成autorelease pool。精简的示例代码如下,详细代码请见附件中的memman-run-loop-without-pool.m。

  1. int main(int argc, char**argv)
  2. {
  3. NSLog(@"No autorelasePool created\n");
  4. NSLog(@"create an instance of ClassA\n");
  5. ClassA *obj1 = [[ClassA alloc] init];
  6. NSDate *now = [[NSDate alloc] init];
  7. NSTimer *timer = [[NSTimer alloc] initWithFireDate:now
  8. interval:0.0
  9. target:obj1
  10. selector:@selector(createClassB)
  11. userInfo:nil
  12. repeats:NO];
  13. NSRunloop *runLoop = [NSRunLoop currentRunLoop];
  14. [runLoop addTimer:timer forMode:NSDefaultRunLoopMode];
  15. [timer release];
  16. [now release];
  17. [runLoop run]; //在新loop中调用一函数,生成ClassB的autorelease实例
  18. NSLog(@"Manually release the instance of ClassA\n");
  19. [obj1 release];
  20. return 0;
  21. }

输出如下:

No autorelasePool created

create an instance of ClassA

create an instance of ClassB and autorelease

ClassB destroyed

Manually release the instance of ClassA

ClassA destroyed

我们可以看出来,我们并没有创建任何autorelease pool,可是ClassB的实例依然被自动销毁了,这说明新的run loop自动创建了一个autorelease pool,这个pool在新的run loop结束的时候会销毁自己(并自动release所包含的对象)。

补充说明

在研究retain count的时候,我不建议用NSString。因为在下面的语句中,

  1. NSString *str1 = @”constant string”;

str1的retain count是个很大的数字。Objective-C对常量字符串做了特殊处理。

当然,如果你这样创建NSString,得到的retain count依然为1

  1. NSString *str2 = [NSString stringWithFormat:@”123”];

示例代码文件链接:http://files.cnblogs.com/VinceYuan/objective-c-memman.zip

Objective-C内存管理教程和原理剖析(四)的更多相关文章

  1. iPhone/Mac Objective-C内存管理教程和原理剖析

    http://www.cocoachina.com/bbs/read.php?tid-15963.html 版权声明 此文版权归作者Vince Yuan (vince.yuan#gmail.com)所 ...

  2. Objective-C内存管理教程和原理剖析(三)

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

  3. Objective C内存管理之理解autorelease------面试题

    Objective C内存管理之理解autorelease   Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的A ...

  4. Objective C 内存管理[转]

    1  配对原则 alloc – release new – release retain - release copy – release 2  new和alloc-init的区别 (1)区别只在于a ...

  5. C++动态内存管理与源码剖析

    引言 在本篇文章中,我们主要剖析c++中的动态内存管理,包括malloc.new expression.operator new.array new和allocator内存分配方法以及对应的内存释放方 ...

  6. 内存管理cpuset,mempolicy[原理]

    介绍cpuset,mbind,set_mempolicy在内存管理上的应用 change log :确定先从mempolicy的man 手册翻译开始研究,计划如下 .先从man手册入手,通过实现mem ...

  7. objective C 内存管理及属性方法具体解释

    oc为每一个对象提供一个内部计数器.这个计数器跟踪对象的引用计数,当对象被创建或拷贝时.引用计数为1.每次保持对象时,调用retain接口.引用计数加1.假设不需要这个对象时调用release,引用计 ...

  8. Linux用户管理 权限管理 内存管理 网络管理命令 (第四天)

    默认添加的用户会自动加入和用户名一样的组中su 切换用户查看当前登陆的用户: whoami id`查看当前用户属于哪个组:groupsgroupadd 组名 添加组groupdel 组名 删除组gre ...

  9. mybatis教程之原理剖析

    MyBatis是目前非常流行的ORM框架,功能很强大,然而其实现却比较简单.优雅.本文通过代理的方式来看下其实现 方式一:传统API方式 @Test public void add() throws ...

随机推荐

  1. [置顶] 【cocos2d-x入门实战】微信飞机大战之三:飞机要起飞了

    转载请表明地址:http://blog.csdn.net/jackystudio/article/details/11730601 不过明眼人一看就知道起飞的不是飞机,是背景,相对运动引起的错觉. 1 ...

  2. java 书籍推荐 JavaEE程序员必读图书大推荐

    java 书籍推荐 JavaEE程序员必读图书大推荐 转自:http://www.cnblogs.com/xlwmin/articles/2192775.html 下面是我根据多年的阅读和实践经验,给 ...

  3. YBC中国国际青年创业计划

    YBC中国国际青年创业计划 中国青年创业国际计划(简称YBC)是共青团中央.中华全国青年联合会.中华全国工商业联合会共同倡导发起的青年创业教育项目.该项目参考总部在英国的青年创业国际计划( Youth ...

  4. 2016.09.01 html5兼容

    <!--[if lt IE 9]>  <script src="http://apps.bdimg.com/libs/html5shiv/3.7/html5shiv.min ...

  5. arcgis for javascript之ArcGISDynamicMapServiceLayer图层控制的实现

    图层控制是非常多GIS系统里面必须的一个小功能,本文就说说arcgis for javascript下ArcGISDynamicMapServiceLayer图层控制的实现方式.首先看图: 实现效果 ...

  6. Dreamweaver PHP代码护眼配色方案

    结果展示 [1]主菜单选择编辑->首选项.在分类中选择"字体".设置代码视图的字体为Courier New [2]在分类中选择 "代码颜色",点击 &qu ...

  7. 【JavaScript脚本编程技术详解-----(一)】

    首先说明,本系列教程是写给有一定的JavaScript编程基础的同学看的,最好还有其它的编程语言经验,因为里面可能涉及一些其它的程序设计语言写的源代码,这都是我自己总结的经验,我喜欢在学习一门新的编程 ...

  8. Java面试题之J2EE是什么

    J2EE是Sun公司提出的多层(multi-diered),分布式(distributed),基于组件(component-base)的企业级应用模型(enterpriese application ...

  9. ListBox第一行字体比其他行小

    ListBox第一行字体比其他行小,把字体设置成“宋体”就可以了.

  10. Oracle中使用透明网关链接到Sqlserver[Z]

    Oracle中使用透明网关链接到Sqlserver 在最近项目中需要从Oracle中访问SQL Server数据库, 自然想到了透明网关. 因为Oracle数据库是Linux上的, 而Linux上的O ...