内存管理:

  • 确保在须要的时候分配内存,在程序运行结束时释放占用的内存
  • 假设仅仅分配内存而不释放内存,则会发生内存泄漏(leak memory),程序的内存占用量不断添加。终于会被耗尽并导致程序崩溃。
  • 不要使用不论什么刚释放的内存,否则可能误用陈旧的数据。假设内存已经载入了其它数据,将会破坏这些新数据。

9.1 对象生命周期

对象的生命周期:

  1. 诞生:通过alloc或new方法实现
  2. 生存:接受消息并运行操作
  3. 交友:通过复合以及向方法传递函数
  4. 死去:被释放掉

9.11 引用计数

关于引用计数的操作:

  • 添加对象的保留计数器的值:发送retain 。方法:-(id) retain //返回值为id类型
[[Car retain] setTire: tire atIndex:2];//car对象保留计数器的值+1并运行setTire的操作
  • 降低对象的保留计数器的值:发送release。方法:(oneway void)release;
  • 获得保留计数器当前的值:retainCount。方法:-(NSUInteger) retainCount;//格式化方法:%ld
  • 对象的保留计数器归0时,系统会自己主动向对象发送dealloc消息。
  • 能够在自己的对象中重写dealloc方法,这样能够释放掉已经分配的全部相关资源,不能直接调用dealloc方法。

9.12 对象全部权

  • 某个实体拥有一个对象时,该实体就要负责将其拥有的对象进行清理

    • 假设一个对象内有指向其它对象的实例变量,则称该对象拥有这些对象
    • 假设一个函数创建了一个对象。则称该函数拥有这个对象
main(){
Car *car = [Car new];
Engine *engine = [Engine new];//engine拥有engine对象 [car setEngine: engine];//car拥有engine对象
}

注意:main()和Car类都拥有engine对象,怎样释放?

  • 让Car类在setEngie方法中保留engine对象。main()负责释放engine对象,Car类完毕任务时再释放engine对象

9.13 訪问方法中的保留和释放

-(void)setEngine: (Engine *)newEngine
{
[newEngine retain]; //先保留新的对象
[engine release]; //释放旧的对象
engine = newEngine;

9.14 自己主动释放

-(NSString *) description
{
NSString *description = [[NSString alloc] initWithFormat:@"I am %d years old", 4];
return (destription);
} main{
NSString *desc = [someObject description];
NSLog(@"@",desc);
[desc release];
}

注意:在description方法中创建的字符串对象怎样释放?

9.15 全部对象放入池中

-(id)autorelease;//返回接受这条消息的对象
  • 当给一个对象发送autorelease消息时,是将对象加入到了自己主动释放池中,当自己主动释放池被销毁时,会像该池中的全部对象发送release消息。
-(NSString *) description
{
NSString *description = [[NSString alloc] initWithFormat:@"I am %d years old", 4];
return ([destription autorelease]);//对象暂时放入池中,等调用NSLog代码结束后。自己主动释放池会被自己主动销毁
} main(){
NSLog(@"@",[someObject description]);
}

9.16 自己主动释放池销毁时间 略

9.17 自己主动释放池的工作流程


int main ()
{
NSAutoreleasePool *pool;
pool = [[NSAutoreleasePool alloc] init]; RetainTracker *tracker;
tracker = [RetainTracker new]; // count: 1 [tracker retain]; // count: 2
[tracker autorelease]; // count: still 2,自己主动释放池有一个引用指向了该对象,当自己主动释放池被销毁时。将给tracker对象发送一条release消息。保留计数器的值仍然大于0,仍处于活动状态。 [tracker release]; // count: 1 NSLog (@"releasing pool");
[pool release]; //dealloc方法调用 return (0);
}

9.2 Cocoa的内存管理规则

  • 使用new。alloc,或copy方法创建对象时。该对象的保留计数器为1。

  • 假设通过其它对象获得一个对象时,假设该对象的保留计数器值为1,并且一景被设置为自己主动释放,那么不须要运行不论什么操作确保该对象得到清理。
  • 假设打算一段时间拥有对象,则须要保留它并确保在操作完毕时释放它。

  • 假设保留了某个对象,就须要终于释放或自己主动释放该对象。

    必须保持retain方法和release方法的使用次数相等。

注意:当拥有一个对象的时候。须要弄清楚:怎样获得对象的?打算拥有多长时间?

9.21 暂时对象

并未打算长期拥有对象的情况下:暂时对象

  • 假设是用new,alloc。copy方法获得的这个对象。就须要安排好该对象的内存释放
  • new。alloc,copy以外的方法获得对象。则能够假设该对象被返回时保留计数器的值是1并且被设置为自己主动释放。

9.22 拥有对象

在多段代码中一直拥有某个对象。将她们加入到诸如NSArray或NSDictionary集合中

  • 假设使用了new,alloc。copy方法获得了一个对象。仅仅须要在拥有该对象的dealloc方法中释放它就可以。

-(void)dostuff
{
flonkArray = [NSMutableArray new]; //count:1
}
-(void) dealloc
{
[flonkArray release]; //count:0
[super dealloc];
}
  • 假设使用new。alloc。copy以外的方法获得了一个对象。须要保留该对象,由于在事件循环结束后或自己主动释放池被销毁时,该对象会收到一条release消息。

-(void)dostuff
{
flonkArray = [NSMutableArray arrayWithCapacity:17]; //count:1,autoreleased }
-(void) dealloc
{
[flonkArray release]; //count:0
[super dealloc];
}

注意:自己主动释放池被清理的时间是全然确定的:在代码中你自己手动销毁;使用AppKit时在事件循环结束时结束。

9.23 垃圾回收:自己主动内存管理机制

垃圾回收器定期检查变量和对象并且跟踪它们的指针,发现没有不论什么变量指向某个对象时,就将该对象视为应该丢弃的垃圾。

假设实例变量指向某个对象,一定要将该实例赋值为nil。取消对该对象的引用并告知垃圾回收器该对象能够清理了。

注意:

  • 垃圾回收仅仅支持OSX开发,无法用在ios应用程序上。苹果公司不建议在自己的代码中使用autorelease方法,也不要使用会返回自己主动释放对象的一些便利的方法:stringWith:
  • 垃圾回收器在运行时工作。通过返回的代码定期检查对象

9.24 自己主动引用计数

  • 自己主动引用计数(automatic refrence counting。ARC):系统追踪对象并决定哪一个仍会使用,哪一个不会再用到。

  • ARC在编译时进行工作的,在代码中插入了retain和release语句。

  • 有效范围:可保留的对象指针

    • 代码块指针
    • Objective-C指针
    • 通过attribute((NSObject))类型定义的指针
  • 使用ARC满足的条件:

    • 能够确定哪些对象须要内存管理
    • 能够表面怎样管理对象
    • 有可行的办法传递对象的全部权
  • A引用了B。B的引用计数器+1,强指针。被引用的+1

  • A释放了B,B的引用计数器-1;被释放的-1

  • 归零弱引用:zeroing weak reference 若引用的对象被释放的情况下,若引用会被设置为0

声明归零弱引用:

  • _weak NSString *mystring
  • @property (weak) NSString *myString

注意:内存管理的关键字和特性是不能一起用的

垃圾回收机制禁用的前提下才干使用ARC

转换之前确保代码符合ARC的需求

一旦转换成ARC版本号,就不能够再恢复了

  • 拥有者权限:为了让ARC便于工作,须要告诉编译器哪个对象时指针的拥有者。

    • (_bridge)传递指针但不会传递它的全部权
    cfstring = (_bridge CFStringRef)theString;
    //指针的全部权仍然由theString保留
    • (_bridge_retain):全部权转移到non-ROP上

      cfstring = (_bridge_retain CFStringRef)theString;
      //cfstring拥有指针并且保留计数器+1
    • (_bridge_transfer):全部权交给ROP

      ARC拥有对象并能确保它会像其它ARC对象一样得到释放

9.3 异常

NSException类来表示异常

  • 抛出异常(提出异常):处理异常的行为,通知异常的行为
  • 捕捉异常:处理被抛出的异常的行为

假设一个异常被抛出可是没有被捕捉到。程序会在异常断点处停止运动并通知有这个异常。

9.31 与异常有关的关键字

  • @try:定义用来測试的代码块决定是否抛出异常
  • @catch:定义用来处理已抛出异常的代码块
  • @finally:不管是否有抛出异常都会运行代码块
  • @throw:抛出异常

9.32 捕捉不同类型的异常

  • 多个@catch代码块。处理代码应该依照从详细到抽象的顺序排序

9.33 抛出异常

  • 当程序检測到了异常。就必须向处理它的代码块报告这个异常

    • 使用@“throw异常名”
    • 向某个NSException对象发送raise消息
NSException *theException = [NSException exceptionWithName: ];
@throw theException; //抛出异常,能够用在其它对象上
[theException rasie];//抛出异常,raise仅仅对NSException对象有效

[学习笔记—Objective-C]《Objective-C-基础教程 第2版》第九章 内存管理的更多相关文章

  1. Objective-C 基础教程第九章,内存管理

    目录 Object-C 基础教程第九章,内存管理 前言: 对象生命周期 引用计数 RetainCount1项目例子 对象所有权 访问方法中的保留和释放 自动释放 所有对象放入池中 自动释放池的销毁时间 ...

  2. 《python基础教程(第二版)》学习笔记 文件和素材(第11章)

    <python基础教程(第二版)>学习笔记 文件和素材(第11章) 打开文件:open(filename[,mode[,buffering]]) mode是读写文件的模式f=open(r' ...

  3. 《python基础教程(第二版)》学习笔记 类和对象(第7章)

    <python基础教程(第二版)>学习笔记 类和对象(第7章) 定义类class Person:    def setName(self,name):        self.name=n ...

  4. 《python基础教程(第二版)》学习笔记 函数(第6章)

    <python基础教程(第二版)>学习笔记 函数(第6章) 创建函数:def function_name(params):  block  return values 记录函数:def f ...

  5. 《python基础教程(第二版)》学习笔记 语句/循环/条件(第5章)

    <python基础教程(第二版)>学习笔记 语句/循环/条件(第5章) print 'AB', 123 ==> AB 123 # 插入了一个空格print 'AB', 'CD' == ...

  6. 《python基础教程(第二版)》学习笔记 字典(第4章)

    <python基础教程(第二版)>学习笔记 字典(第4章)创建字典:d={'key1':'value1','key2':'value2'}lst=[('key1','value1'),(' ...

  7. 《python基础教程(第二版)》学习笔记 字符串(第3章)

    <python基础教程(第二版)>学习笔记 字符串(第3章)所有的基本的序列操作(索引,分片,乘法,判断成员资格,求长度,求最大最小值)对字符串也适用.字符串是不可以改变的:格式化输出字符 ...

  8. 《python基础教程(第二版)》学习笔记 列表/元组(第2章)

    <python基础教程(第二版)>学习笔记 列表/元组(第2章)序列中的下标从0开始x='ABC' ==> x[0]='A', x[1]='B', x[2]='C'负数索引从右边开始 ...

  9. 《python基础教程(第二版)》学习笔记 基础部分(第1章)

    <python基础教程(第二版)>学习笔记 基础部分(第1章)python常用的IDE:Windows: IDLE(gui), Eclipse+PyDev; Python(command ...

随机推荐

  1. 洛谷——P1529 回家 Bessie Come Home

    P1529 回家 Bessie Come Home 题目描述 现在是晚餐时间,而母牛们在外面分散的牧场中. 农民约翰按响了电铃,所以她们开始向谷仓走去. 你的工作是要指出哪只母牛会最先到达谷仓(在给出 ...

  2. ZOJ 3949 Edge to the Root(想法)(倍增)

    Edge to the Root Time Limit: 1 Second      Memory Limit: 131072 KB Given a tree with n vertices, we ...

  3. HashMap的实现原理 HashMap底层实现,hashCode如何对应bucket?

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 数组和链表组合成的链表散列结构,通过hash算法,尽量将数组中的数据分布均匀,如果has ...

  4. 「HNOI2013」游走

    「HNOI2013」游走 题目描述 一个无向连通图,顶点从 \(1\) 编号到 \(N\) ,边从 \(1\) 编号到 \(M\) .小 \(Z\) 在该图上进行随机游走,初始时小 \(Z\) 在 \ ...

  5. JZYZOJ1454 NOIP2015 D2T3_运输计划 二分 差分数组 lca tarjan 树链剖分

    http://172.20.6.3/Problem_Show.asp?id=1454 从这道题我充分认识到我的脑子里好多水orz. 如果知道了这个要用二分和差分写,就没什么思考上的难点了(屁咧你写了一 ...

  6. 【数据结构】Not so Mobile (6-9)

    [UVA839]Not so Mobile 算法入门经典第6章6-9(P157) 题目大意:输入一个树状天平,根据力矩相等原则判断是否平衡. 试题分析:貌似没有什么难点…… #include<i ...

  7. Codeforces 610C:Harmony Analysis(构造)

    [题目链接] http://codeforces.com/problemset/problem/610/C [题目大意] 构造出2^n个由1和-1组成的串使得其两两点积为0 [题解] 我们可以构造这样 ...

  8. 数据库系统入门 | Oracle Linux上部署Oracle 11g服务,并实现SSH远程登录管理

    文章目录 写在前面 一.实验内容 二.实验前期准备 1.软件目录 2.准备一些配置文件.脚本文件 三.实验方案(具体步骤) (一)在虚拟机上安装Oracle Linux (二)在Linux上安装Ora ...

  9. PHP stream 学习笔记一(同步阻塞 IO 模型)

    原文http://blog.csdn.net/shagoo/article/details/6396089 [root@localhost php]# vi server_one.php <?p ...

  10. Java 导出大批量数据excel(百万级)(转载)

    参考资料:http://bbs.51cto.com/thread-1074293-1-1.html                 http://bbs.51cto.com/viewthread.ph ...