OC学习笔记之OC对象的内存管理二
2014-05-08 19:58
323 查看
一、OC内存管理的原则
1> 谁创建对象,谁release
每当alloc、new或者copy出一个新对象的时候,它的初始引用计数器值就为1,就要release,使得它的引用计数器保持平衡。
2> 谁retain,谁release
每当调用retain方法,使得计数器 +1,就要release,不论这个对象是怎么产生。
3> 谁使用,谁retain
每当使用一个对象时,就要retain,这样,在它自己release时就可以保证对象没有被回收,成为僵尸对象,从而正常使用。
总的来说,这两三条就是OC对象内存管理的核心原则,有始有终,有加必有减,曾经让引用计数器加了1,最后就要让它减回来。
下面小桥使用这几条原则,有两个类的实现文件,其它都重写了 dealloc方法:
二、OC多对象的内存管理
上面的Person和Car的对象独立时,内存管理简单明了,但是如果当两个对象联系起来时,就要注意。比如:
上面的错误的因为在访问car中speed成员之前,该对象已经被回收了,成了僵尸对象,你可能会说,把那两句顺序换一下不就好了?虽然这样做这里不会再报错,但这绝不是一种安全做法,因为我们依然不能肯定在访问之前,对象有没有被回收,只有肯定对象存在才是安全的访问。
这里的根本错误是没有遵守原则3,谁使用,谁retain,既然你使用了c对象,那么必须retain来保证你可以一直安全地使用它,而不用担心,不知道什么时候它被回收,因为只要你retain之后没有release,它就一直都在。所以安全、严谨的做法是在setter方法中retain一下:
setter方法中的条件,是为了过虑重复调用setter方法赋值同一car,以免写几个 p.car = c; 就retain几次,这不符合retain和release的平衡原则。
三、@property的参数
小桥在前面的笔记中有提到这个OC关键字,它自动生成setter和getter方法,它还有带参数的形态,参数类型有4类:
一、setter方法中的内存管理参数
1> retain:和上图中的setter方法中写的一样,release旧值,retain新值,当然这是用于OC中的对象,而不是基本数据类型
2> assign:直接赋值,也就是以前的setter方法,这是用于基本数据类型的,也是@property默认使用的
3> copy:和retain类似
二、与生成setter和getter方法相关
1> readwrite:同时生成setter和getter方法的声明、实现,这是@property默认使用的
2> readonly:只读,只生成getter方法的声明和实现
三、多线程管理
1> nonatomic:性能高,建议用的参数
2> atomic:性能低,但是是默认使用的。
四、setter和getter方法的名称
1> setter:自定义setter方法的名称,注意方法中要带冒号
2> getter:自定义getter方法的名称,一般返回bool类型的getter方法要使用,把getter方法改成isXxx
这样,@property就自动帮我们写好setter方法中内存管理代码了,但是在dealloc中还是要release相关的对象
1> 谁创建对象,谁release
每当alloc、new或者copy出一个新对象的时候,它的初始引用计数器值就为1,就要release,使得它的引用计数器保持平衡。
2> 谁retain,谁release
每当调用retain方法,使得计数器 +1,就要release,不论这个对象是怎么产生。
3> 谁使用,谁retain
每当使用一个对象时,就要retain,这样,在它自己release时就可以保证对象没有被回收,成为僵尸对象,从而正常使用。
总的来说,这两三条就是OC对象内存管理的核心原则,有始有终,有加必有减,曾经让引用计数器加了1,最后就要让它减回来。
下面小桥使用这几条原则,有两个类的实现文件,其它都重写了 dealloc方法:
// // 文件:Person.m // 项目:博客笔记 // 作者:葬花 桥 // 日期:14-5-8 // 版权:Copyright (c) 2014年 itcast. All rights reserved. // #import "Person.h" @implementation Person - (void)setCar:(Car *)car { _car = car; } - (void)dealloc { NSLog(@"person被回收了!"); [superdealloc]; } @end // // 文件:Car.m // 项目:博客笔记 // 作者:葬花 桥 // 日期:14-5-8 // 版权: Copyright (c) 2014年 itcast. All rights reserved. // #import "Car.h" @implementation Car - (void)dealloc { NSLog(@"car被回收了!"); [superdealloc]; } @end
二、OC多对象的内存管理
上面的Person和Car的对象独立时,内存管理简单明了,但是如果当两个对象联系起来时,就要注意。比如:
上面的错误的因为在访问car中speed成员之前,该对象已经被回收了,成了僵尸对象,你可能会说,把那两句顺序换一下不就好了?虽然这样做这里不会再报错,但这绝不是一种安全做法,因为我们依然不能肯定在访问之前,对象有没有被回收,只有肯定对象存在才是安全的访问。
这里的根本错误是没有遵守原则3,谁使用,谁retain,既然你使用了c对象,那么必须retain来保证你可以一直安全地使用它,而不用担心,不知道什么时候它被回收,因为只要你retain之后没有release,它就一直都在。所以安全、严谨的做法是在setter方法中retain一下:
setter方法中的条件,是为了过虑重复调用setter方法赋值同一car,以免写几个 p.car = c; 就retain几次,这不符合retain和release的平衡原则。
三、@property的参数
小桥在前面的笔记中有提到这个OC关键字,它自动生成setter和getter方法,它还有带参数的形态,参数类型有4类:
一、setter方法中的内存管理参数
1> retain:和上图中的setter方法中写的一样,release旧值,retain新值,当然这是用于OC中的对象,而不是基本数据类型
2> assign:直接赋值,也就是以前的setter方法,这是用于基本数据类型的,也是@property默认使用的
3> copy:和retain类似
二、与生成setter和getter方法相关
1> readwrite:同时生成setter和getter方法的声明、实现,这是@property默认使用的
2> readonly:只读,只生成getter方法的声明和实现
三、多线程管理
1> nonatomic:性能高,建议用的参数
2> atomic:性能低,但是是默认使用的。
四、setter和getter方法的名称
1> setter:自定义setter方法的名称,注意方法中要带冒号
2> getter:自定义getter方法的名称,一般返回bool类型的getter方法要使用,把getter方法改成isXxx
// // 文件:Person.h // 项目:博客笔记 // 作者:葬花 桥 // 日期:14-5-8 // 版权: Copyright (c) 2014年 itcast. All rights reserved. // #import <Foundation/Foundation.h> #import "Car.h" @interface Person :NSObject @property (nonatomic,assign)int age; @property (nonatomic,retain)Car *car; @end
这样,@property就自动帮我们写好setter方法中内存管理代码了,但是在dealloc中还是要release相关的对象
相关文章推荐
- 黑马程序员---OC学习笔记之集合对象的内存管理
- OC学习笔记之OC对象的内存管理
- 黑马程序员-7-Objective-C学习笔记(OC对象深入认识)
- 黑马程序员学习笔记_OC之内存管理3ARC
- 【学习笔记】【OC语言】创建对象
- Objective-C 学习笔记(2) -- OC的内存管理
- 黑马程序员学习笔记_OC之面向对象思想
- 黑马程序员---OC学习笔记之autorelease快速创建对象的应用
- 【cocos2d-x 3.x 学习笔记】对象内存管理
- ios学习笔记-(oc基础-面向对象小系统)
- 黑马程序员-IOS学习笔记 OC创建对象时 系统做了些什么
- 黑马程序员学习笔记_OC之内存管理1
- 黑马程序员---学习笔记23:OC基础(10)内存管理
- 黑马程序员-IOS学习笔记 OC 关于对象方法类方法的一些概念
- ios学习笔记之OC篇(一):复制对象的方法
- Objective-C学习笔记(四):OC之分类、类对象、description方法和SEL
- 黑马程序员-ios学习笔记 oc 类和对象
- 黑马程序员-OC学习笔记-----内存管理
- 黑马程序员-IOS学习笔记-OC基础OC类和对象