[学习笔记—Objective-C]《Objective-C-基础教程 第2版》第九章 内存管理
内存管理:
- 确保在须要的时候分配内存,在程序运行结束时释放占用的内存
- 假设仅仅分配内存而不释放内存,则会发生内存泄漏(leak memory),程序的内存占用量不断添加。终于会被耗尽并导致程序崩溃。
- 不要使用不论什么刚释放的内存,否则可能误用陈旧的数据。假设内存已经载入了其它数据,将会破坏这些新数据。
9.1 对象生命周期
对象的生命周期:
- 诞生:通过alloc或new方法实现
- 生存:接受消息并运行操作
- 交友:通过复合以及向方法传递函数
- 死去:被释放掉
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版》第九章 内存管理的更多相关文章
- Objective-C 基础教程第九章,内存管理
目录 Object-C 基础教程第九章,内存管理 前言: 对象生命周期 引用计数 RetainCount1项目例子 对象所有权 访问方法中的保留和释放 自动释放 所有对象放入池中 自动释放池的销毁时间 ...
- 《python基础教程(第二版)》学习笔记 文件和素材(第11章)
<python基础教程(第二版)>学习笔记 文件和素材(第11章) 打开文件:open(filename[,mode[,buffering]]) mode是读写文件的模式f=open(r' ...
- 《python基础教程(第二版)》学习笔记 类和对象(第7章)
<python基础教程(第二版)>学习笔记 类和对象(第7章) 定义类class Person: def setName(self,name): self.name=n ...
- 《python基础教程(第二版)》学习笔记 函数(第6章)
<python基础教程(第二版)>学习笔记 函数(第6章) 创建函数:def function_name(params): block return values 记录函数:def f ...
- 《python基础教程(第二版)》学习笔记 语句/循环/条件(第5章)
<python基础教程(第二版)>学习笔记 语句/循环/条件(第5章) print 'AB', 123 ==> AB 123 # 插入了一个空格print 'AB', 'CD' == ...
- 《python基础教程(第二版)》学习笔记 字典(第4章)
<python基础教程(第二版)>学习笔记 字典(第4章)创建字典:d={'key1':'value1','key2':'value2'}lst=[('key1','value1'),(' ...
- 《python基础教程(第二版)》学习笔记 字符串(第3章)
<python基础教程(第二版)>学习笔记 字符串(第3章)所有的基本的序列操作(索引,分片,乘法,判断成员资格,求长度,求最大最小值)对字符串也适用.字符串是不可以改变的:格式化输出字符 ...
- 《python基础教程(第二版)》学习笔记 列表/元组(第2章)
<python基础教程(第二版)>学习笔记 列表/元组(第2章)序列中的下标从0开始x='ABC' ==> x[0]='A', x[1]='B', x[2]='C'负数索引从右边开始 ...
- 《python基础教程(第二版)》学习笔记 基础部分(第1章)
<python基础教程(第二版)>学习笔记 基础部分(第1章)python常用的IDE:Windows: IDLE(gui), Eclipse+PyDev; Python(command ...
随机推荐
- 洛谷——P1529 回家 Bessie Come Home
P1529 回家 Bessie Come Home 题目描述 现在是晚餐时间,而母牛们在外面分散的牧场中. 农民约翰按响了电铃,所以她们开始向谷仓走去. 你的工作是要指出哪只母牛会最先到达谷仓(在给出 ...
- 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 ...
- HashMap的实现原理 HashMap底层实现,hashCode如何对应bucket?
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha 数组和链表组合成的链表散列结构,通过hash算法,尽量将数组中的数据分布均匀,如果has ...
- 「HNOI2013」游走
「HNOI2013」游走 题目描述 一个无向连通图,顶点从 \(1\) 编号到 \(N\) ,边从 \(1\) 编号到 \(M\) .小 \(Z\) 在该图上进行随机游走,初始时小 \(Z\) 在 \ ...
- JZYZOJ1454 NOIP2015 D2T3_运输计划 二分 差分数组 lca tarjan 树链剖分
http://172.20.6.3/Problem_Show.asp?id=1454 从这道题我充分认识到我的脑子里好多水orz. 如果知道了这个要用二分和差分写,就没什么思考上的难点了(屁咧你写了一 ...
- 【数据结构】Not so Mobile (6-9)
[UVA839]Not so Mobile 算法入门经典第6章6-9(P157) 题目大意:输入一个树状天平,根据力矩相等原则判断是否平衡. 试题分析:貌似没有什么难点…… #include<i ...
- Codeforces 610C:Harmony Analysis(构造)
[题目链接] http://codeforces.com/problemset/problem/610/C [题目大意] 构造出2^n个由1和-1组成的串使得其两两点积为0 [题解] 我们可以构造这样 ...
- 数据库系统入门 | Oracle Linux上部署Oracle 11g服务,并实现SSH远程登录管理
文章目录 写在前面 一.实验内容 二.实验前期准备 1.软件目录 2.准备一些配置文件.脚本文件 三.实验方案(具体步骤) (一)在虚拟机上安装Oracle Linux (二)在Linux上安装Ora ...
- PHP stream 学习笔记一(同步阻塞 IO 模型)
原文http://blog.csdn.net/shagoo/article/details/6396089 [root@localhost php]# vi server_one.php <?p ...
- Java 导出大批量数据excel(百万级)(转载)
参考资料:http://bbs.51cto.com/thread-1074293-1-1.html http://bbs.51cto.com/viewthread.ph ...