1. 苹果官方规定的内存管理原则
创建谁release : 如果你通过alloc、new或copy、mutableCopy来创建一个对象,那么你必须调用release或autorelease。
谁retain谁release :只要你调用了retain,就必须调用一次release
总结一下就是
有加就有减 ,曾经让对象的计数器+1,就必须在最后让对象计数器-1
在自己负责的区域内(某个方法范围内、某个对象内等。):有+,就得有-。
示例代码:
有一个Car类和Person类。
Person.h代码如下:
#import <Foundation/Foundation.h>
#import "Car.h"
@interface Person : NSObject
@property (nonatomic,retain) Car *car;
- (void)setCar:(Car *)car;
- (void)goLasa;
@end
Person.m的代码如下:
#import "Person.h"
@implementation Person
- (void)setCar:(Car *)car{
if(_car != car){
[_car release];
_car = [car retain];
}
}
- (void)dealloc{
[_car dealloc];
[super dealloc];
}
- (void)goLasa{
[_car run];
}
@end
这里最关键的代码就是setCar方法中的代码,setCar方法中的代码是@property中retain参数的实现方式,即先判断参数与旧值是否一样,如果不一样,则释放(release)旧值,并retain新值。因为Person对象对Car进行了retain,根据苹果内存管理原则,Person同样需要负责对Car进行release,什么时候进行release适合呢?自然就是Person类dealloc函数中即Person类释放前对属性Car也release一下。
(1)让Person类拥有car属性、dog属性,自己编写car属性与dog属性的get、set方法(复习内存管理代码)
(2)通过@property关键字自动生成内存管理代码
可以自己编写类属性的set,get方法,也可以通过@property参数来自动生成内存管理代码。
上面Person,Car的代码,通过指定@property参数进行内存管理的代码如下:
Person.h中指定代码是retain就可以了。
@property (nonatomic,retain) Car *car;
但是在Person.m中不再需要重写set方法中的代码,因为retain参数默认就是
- (void)setCar:(Car *)car{
if(_car != car){
[_car release];
_car = [car retain];
}
}
还是需要重写dealloc函数,在里面添加 Car的release。
- (void)dealloc{
[_car dealloc];
[super dealloc];
}
2. @property参数
控制set方法的内存管理
retain : release旧值,retain新值(用于OC对象),要配合nonatomic使用。
assign : 直接赋值,不做任何内存管理(默认,用于非OC对象类型)
copy : release旧值,copy新值(一般用于NSString *)
控制需不需生成set方法
readwrite :同时生成set方法和get方法(默认)
readonly :只会生成get方法
多线程管理
atomic :性能低(默认)
nonatomic :性能高(为iOS系统开发软件建议使用,为mac开发软件可以使用atomic)
控制set方法和get方法的名称
setter : 设置set方法的名称,一定有个冒号:
getter : 设置get方法的名称
@property (nonatomic, retain, setter = setUserName:, getter = getUserName) NSString *name;
一般只有BOOL类型的属性的get方法才会使用getter修改一下方法名为isXxxx,其他很少用的。
@property (nonatomic, assign) BOOL rich;
@property (nonatomic, assign, getter = isRich) BOOL rich;