虽然iOS已经有了ARC帮你自动管理内存,但在有些项目中必须采用手动的方式,而且在懂得手动管理内存的情况下会是自己的代码更加完善

众所周知,基于手动管理内存的情况下必然涉及到 relese  retain autorelese copy 等。

其中 relese就是把对象的引用计数减一    retain表示把对象的引用计数加一   autorelese则是为一个叫做  内存池 的东西准备的

@autoreleasepool {

}

当你创建的对象加入到了内存池中,并且创建对象时用了  autorelese,则当内存池销毁时会自动帮对象调用autorelese

而copy则是拷贝一份 此时原有的对象其引用计数并不增加  ,当然涉及到拷贝的话又分为 浅拷贝 和 深拷贝, 不懂得可以上网查 很多的。

上面这张图是官网上的。可以看看  描述的挺好的。下面通过一点小代码来说明下今天的主题:

注意:relese autorelese  retain  他们操作的是对象的引用计数  而对于该变量本身是无影响的(除非所指的对象引用计数为零了),

如:

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib. NSString *a = [[NSString alloc]initWithUTF8String:"women"];//a所指的对象引用计数为1 NSLog(@"a reference is : %d",a.retainCount);
NSLog(@"a = %@ ",a);
NSString *b = a;//b 和 a 指向同一个对象
[b retain];//b 把 应用计数加一了
NSLog(@"a reference is : %d",a.retainCount);
NSLog(@"b reference is : %d",b.retainCount);
NSLog(@"b = %@ ",b); [a release]; NSLog(@"after a relese a reference is : %d",a.retainCount);
NSLog(@"agter a relese b reference is : %d",b.retainCount);
NSLog(@"a = %@ ",a);
NSLog(@"b = %@ ",b); }

上面代码的输出:

2013-07-30 18:53:02.679 MemoryDemo[4892:c07] a  reference is : 1

2013-07-30 18:53:02.680 MemoryDemo[4892:c07] a = women 

2013-07-30 18:53:02.681 MemoryDemo[4892:c07] a  reference is : 2

2013-07-30 18:53:02.681 MemoryDemo[4892:c07] b   reference is : 2

2013-07-30 18:53:02.682 MemoryDemo[4892:c07] b = women 

2013-07-30 18:53:02.682 MemoryDemo[4892:c07] after a relese a  reference is : 1

2013-07-30 18:53:02.683 MemoryDemo[4892:c07] agter a relese b   reference is : 1

2013-07-30 18:53:02.684 MemoryDemo[4892:c07] a = women 

2013-07-30 18:53:02.685 MemoryDemo[4892:c07] b = women 

 相信很容易懂吧。但如果此时我再调用下  [a relese];可以这样吗,a不是已经调用过了relese吗 ?还可以再调用一次 ,当然可以,因为relese操作的只是a 所指对象的引用计数,而不是 把 a 给消失掉了,好吧,我们把代码加上  ,再打印下(又陷阱的)。。。。

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib. NSString *a = [[NSString alloc]initWithUTF8String:"women"];//a所指的对象引用计数为1 NSLog(@"a reference is : %d",a.retainCount);
NSLog(@"a = %@ ",a);
NSString *b = a;//b 和 a 指向同一个对象
[b retain];//b 把 应用计数加一了
NSLog(@"a reference is : %d",a.retainCount);
NSLog(@"b reference is : %d",b.retainCount);
NSLog(@"b = %@ ",b); [a release]; NSLog(@"after a relese a reference is : %d",a.retainCount);
NSLog(@"agter a relese b reference is : %d",b.retainCount);
NSLog(@"a = %@ ",a);
NSLog(@"b = %@ ",b); //新加上的
[a release];
NSLog(@"after a relese a reference is : %d",a.retainCount);
NSLog(@"agter a relese b reference is : %d",b.retainCount);
}

呵呵  ,崩掉了吧  ! 罪魁祸首就在最后的NSLog(),  a再次 relese时  他所指的对象的引用计数已经为零了 ,此时对象已经消失了 ,你再去给他发送消息  ,当然死掉咯

接着看。。。。。

你说一个对象的引用计数有可能为负数吗?? 上面的代码不是因为最后两行不能运行吗? 那你试着把第一行改为

NSString *a = [[NSStringalloc]initWithString:@"women"];

你会看到他正常运行  输出如:

2013-07-30 19:19:19.522 MemoryDemo[5082:c07] a  reference is : -1

2013-07-30 19:19:19.523 MemoryDemo[5082:c07] a = women 

2013-07-30 19:19:19.524 MemoryDemo[5082:c07] a  reference is : -1

2013-07-30 19:19:19.524 MemoryDemo[5082:c07] b   reference is : -1

2013-07-30 19:19:19.525 MemoryDemo[5082:c07] b = women 

2013-07-30 19:19:19.525 MemoryDemo[5082:c07] after a relese a  reference is : -1

2013-07-30 19:19:19.526 MemoryDemo[5082:c07] agter a relese b   reference is : -1

2013-07-30 19:19:19.526 MemoryDemo[5082:c07] a = women 

2013-07-30 19:19:19.527 MemoryDemo[5082:c07] b = women 

2013-07-30 19:19:19.527 MemoryDemo[5082:c07] after a relese a  reference is : -1

2013-07-30 19:19:19.527 MemoryDemo[5082:c07] agter a relese b   reference is : -1

怎么可能,而且全都是-1  ,这时因为这是一个NSString的常量 ,他一直处在 字符串常量池 中 ,生命周期为整个程序  ,所以你看到本来应该崩掉的代码正常运行,

但此时对象的引用计数永远为-1  代表无穷大。。。

最后再来看看,下面的例子: 

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib. //NSString *a = [[NSString alloc]initWithString:@"women"]; NSString *a = [NSString stringWithUTF8String:"women"];
NSLog(@"a reference is : %d",a.retainCount);
NSLog(@"a = %@ ",a);
NSString *b = a;//b 和 a 指向同一个对象
[b retain];//b 把 应用计数加一了
NSLog(@"a reference is : %d",a.retainCount);
NSLog(@"b reference is : %d",b.retainCount);
NSLog(@"b = %@ ",b); [a release]; NSLog(@"after a relese a reference is : %d",a.retainCount);
NSLog(@"agter a relese b reference is : %d",b.retainCount);
NSLog(@"a = %@ ",a);
NSLog(@"b = %@ ",b); [a release];
//NSLog(@"after a relese a reference is : %d",a.retainCount);
// NSLog(@"agter a relese b reference is : %d",b.retainCount);
}

上面的代码主要是把第一句  初始化方法改为了  静态的类方法  非 alloc的

运行试试  崩掉了吧  。。。为什么这也会绷掉呢 ??

这就是autorelese搞的鬼了 ,但好像没看到 autorelese啊

呵呵,这就要怪苹果公司了  他们写的这个方法

NSString *a = [NSString stringWithUTF8String:"women"];
是在后面加了 autorelese的,几乎我所知道的所有的类似这样的 [NSString stringWith...] [UIImage imageWith.....]

[NSArray arrayWith....]等等 ,他们实现的时候都是加入了autorelese的  ,既然你加入了autorelese ,而程序的main.c函数中又有

int main(int argc, char *argv[])

{

@autoreleasepool {

returnUIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegateclass]));

}

}

呵呵 ,这下知道了吧,,你的程序会自动给  在你加入了autorelese的对象  发送relese消息,但此时最后一句代码

[a relese]已经把对象的引用计数变为零了。。。。人家当然不干了 ,所以在我们遇到这样的类似初始化方法时  ,千万要记住 autorelse这个东西。

完结吧!

iOS手动管理内存的更多相关文章

  1. xcode 手动管理内存 的相关知识点总结

    一.XCode4.2以后支持自动释放内存ARC xcode自4.2以后就支持自动释放内存了,但有时我们还是想手动管理内存,这如何处理呢. 很简单,想要取消自动释放,只要在  Build Setting ...

  2. golang手动管理内存

    作者:John Graham-Cumming.   原文点击此处.翻译:Lubia Yang(已失效) 前些天我介绍了我们对Lua的使用,implement our new Web Applicati ...

  3. iOS MRC ARC 内存管理

    转自:http://www.jianshu.com/p/48665652e4e4 1. 什么是内存管理 程序在运行的过程中通常通过以下行为,来增加程序的的内存占用 创建一个OC对象 定义一个变量 调用 ...

  4. iOS 非ARC基本内存管理系列 2-多对象内存管理(3) 利用@property来自动管理内存

    iOS 基本内存管理-多对象内存管理(2)中可以看到涉及到对象的引用都要手动管理内存:每个对象都需要写如下代码 // 1.对要传入的"新车"对象car和目前Person类对象所拥有 ...

  5. jvm是如何管理内存的

    1.JVM是如何管理内存的 Java中,内存管理是JVM自动进行的,无需人为干涉. 了解Java内存模型看这里:java内存模型是什么样的 了解jvm实例结构看这里:jvm实例的结构是什么样的 创建对 ...

  6. iOS开发ARC内存管理技术要点

    本文来源于我个人的ARC学习笔记,旨在通过简明扼要的方式总结出iOS开发中ARC(Automatic Reference Counting,自动引用计数)内存管理技术的要点,所以不会涉及全部细节.这篇 ...

  7. iOS开发ARC内存管理

    本文的主要内容: ARC的本质 ARC的开启与关闭 ARC的修饰符 ARC与Block ARC与Toll-Free Bridging ARC的本质 ARC是编译器(时)特性,而不是运行时特性,更不是垃 ...

  8. iOS夯实:内存管理

    iOS夯实:内存管理 文章转自 内存管理 最近的学习计划是将iOS的机制原理好好重新打磨学习一下,总结和加入自己的思考. 有不正确的地方,多多指正. 目录: 基本信息 旧时代的细节 新时代 基本信息 ...

  9. IOS开发之内存管理--dealloc该写些什么

    在非ARC开发环境中,dealloc是类释放前,清理内存的最后机会.到底那些变量和属性该释放呢,一些特殊的类(nstimer,observer)该怎么释放.需要注意的是不释放会引起内存泄露,过度释放也 ...

随机推荐

  1. 雅居乐在核心产品 "决策"

    2015.6.2 在武汉-- 这是一支谦卑且认真学习,又实实在在做产品的 "产品级敏捷团队". "产品级敏捷团队"--在产品版本号开发的生命周期中.均能共同高效 ...

  2. GitFlow使用说明

    ———————安装--------------- $ git clone --recursive git://github.com/nvie/gitflow.git $ cd gitflow $ [s ...

  3. 经验总结35--IP地址区域匹配

    想知道客服端訪问的IP地址是多少,并知道区域. 一般能够去http://www.ip138.com/,输入IP查询,但没提供比較好的接口,程序使用不方便. 另外有些企业提供一些离线的IP数据库,能够进 ...

  4. 《浪潮之巅》完全系类——IT人士必读经典

    浪潮之巅 第一章 帝国的余辉(AT&T) 浪潮之巅第二章 — 蓝色巨人(IBM) 浪潮之巅第三章 — “水果”公司的复兴 (乔布斯和苹果公司) 浪潮之巅第四章 — 计算机工业的生态链 浪潮之巅 ...

  5. 序列化悍将Protobuf-Net

    序列化悍将Protobuf-Net,入门动手实录 最近在研究web api 2,看了一篇文章,讲解如何提升性能的, 在序列化速度的跑分中,Protobuf一骑绝尘,序列化速度快,性能强,体积小,所以打 ...

  6. 国内ng学习网站

    Ngnice-国内ng学习网站2015-01-25 21:30 by 破狼, 534 阅读, 3 评论,收藏, 编辑 今天给angular新手介绍一个国内开源的ng学习网站http://www.ngn ...

  7. 基于OCR的SeeTest框架可行性分析总结

    总的来说相比其他几个免费框架,SeeTest功能更全面和易用,但收费有点昂贵:License 3500/年:多平台和多语言(基于OCR)还需要额外购买,分别是500/Year和1750$/.详情请查看 ...

  8. libvlc media player in C# (part 2)

    原文 http://www.helyar.net/2009/libvlc-media-player-in-c-part-2/ I gave some simplified VLC media play ...

  9. MVC+Jqgrid

    基于MVC+Jqgrid的列表页面 2014-12-08 12:01 by 刘尼玛, 1583 阅读, 20 评论, 收藏, 编辑 一.前言 “尼玛哥,上周你教我改了下OA系统UI,黄总看了很满意呀. ...

  10. Visual Studio 2010 单元测试--运行测试并查看代码覆盖率

    原文:Visual Studio 2010 单元测试--运行测试并查看代码覆盖率 运行测试并查看代码覆盖率对程序集中的代码运行测试时,可以通过收集代码覆盖率数据来查看正在测试的项目代码部分. 运行测试 ...