(原)OC内存管理
1.内存管理
三种方式:ARC、手动管理、自动释放池
1.1手动管理
手动管理内存中每个对象都拥有一个引用计数
当创建或者复制(alloc、copy)某个对象时 就拥有了对象所有权 计数器+1
当向对象发送retain消息时 也拥有了对象所有权 计数器+1
当向这个对象发送release、autorelease 消息时,计数器-1
当对象的引用计数为0时,系统自动调用dealloc方法,销毁该对象
1.1.1 初始化方法
直接向对象发送retain消息。并在dealloc方法释放该对象
1.1.2 设置方法
直接赋值,不保留对象
直接保留对象,并在dealloc方法里释放该对象
释放旧对象,保留新对象,在dealloc方法中释放对象
1.1.3 dealloc方法
先释放子类对象,在释放父类实例 这一点与调用初始化方法,正好相反
1.1.4 点语法的内存管理
assign: 简单赋值,不更改索引计数(Reference Counting)。同一个地址。适用于基础数据类型 (NSInteger,CGPoint,CGFloat)和C数据类型(int, float, double, char, 等等)
copy:建立一个索引计数为1的对象,然后释放旧对象。适用于如NSArray,NSSet,NSDictionary,NSData的,NSCharacterSet,NSIndexSet,NSString 但是NSMutableArray这样的不可以,Mutable的不能用copy,因为copy返回的是不可变的。
- (void)setName:(NSString *)newName {
if (name != newName) { //判断旧值与新值是否是同一个
[name release]; //释放旧值
name = [newName copy];
}
}
retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1 。适用于其他NSObject和其子类
- (void)setName:(NSString *)newName {
if (name != newName) { //判断旧值与新值是否是同一个
[name release]; //释放旧值
name = [newName retain]; //保留新值 然后赋给就对象
}
}
区别:
assign:直接赋值,只是一个别名
retain:保留这个对象,两个对象指向同一个地址,引用计数为2
copy:新开辟了一个新的内存空间,分别指向了不同的对象,引用计数分别为1 (某些时候copy,相当于retain)
1.1.5 原子性
atomic :多线程下存在线程保护(eg:防止写入),默认
nonatomic:多线程下,不存在线程保护。提高速度
1.1.6 内存中的常见错误
自定义类方法
+ (id)person
{
Person *person =[[Person alloc]init];
return [person autorelease]; // release是错误的, autorelease是正确
}
对象A retain对象B,同时对象B retain A.这是两个对象都没办法释放。
如代理设计模式 一般用assign
1.2 自动释放池
当我们将一个对象发送了autorelease消息。当自动释放池销毁时,会向池中的每个对象发送一次release消息。
1.3 ARC