一、OC内存管理的原则
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
上面的Person和Car的对象独立时,内存管理简单明了,但是如果当两个对象联系起来时,就要注意。比如:
![](https://img-my.csdn.net/uploads/201405/08/1399550716_6851.png)
上面的错误的因为在访问car中speed成员之前,该对象已经被回收了,成了僵尸对象,你可能会说,把那两句顺序换一下不就好了?虽然这样做这里不会再报错,但这绝不是一种安全做法,因为我们依然不能肯定在访问之前,对象有没有被回收,只有肯定对象存在才是安全的访问。
这里的根本错误是没有遵守原则3,谁使用,谁retain,既然你使用了c对象,那么必须retain来保证你可以一直安全地使用它,而不用担心,不知道什么时候它被回收,因为只要你retain之后没有release,它就一直都在。所以安全、严谨的做法是在setter方法中retain一下:
![](https://img-my.csdn.net/uploads/201405/08/1399550716_6284.png)
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相关的对象
一、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相关的对象