Foundation框架-08 集合对象的内存管理
1.操作集合对象对引用计数器的影响(非ARC模式下)
官方内存管理原则
- 当调用alloc、new、copy(mutableCopy)方法产生一个新的对象时,就必须在最后调用一次release或者autorelease
- 当调用retain方法让对象的计数器+1,就必须在最后调用一次release或者autorelease
集合对象的内存管理细节
- 1> 当把一个对象添加到集合中时,这个对象会做了一次retain操作,计数器会+1
- 当一个集合被销毁时,会对集合里面的所有对象做一次release操作,计数器会-1
- 当一个对象从集合中移除时,这个对象会一次release操作,计数器会-1
普遍规律
- 如果方法名是add\insert开头,那么被添加的对象,计数器会+1
- 如果方法名是remove\delete开头,那么被移除的对象,计数器-1
2.copy属性
基本概念,copy的意思是拷贝,复制,即利用一个源对象产生一个副本对象
- 修改源对象的属性和行为,不会影响副本对象
- 修改副本对象的属性和行为,不会影响源对象
copy的使用
- 一个对象可以调用copy或mutableCopy方法来创建一个副本对象
- copy:创建的是不可变的副本(如NSString、NSArray、NSDictionary)
- mutableCopy:创建的是可变副本(如NSMutableString、NSMutableArray、NSMutableDictionary)
使用copy功能的前提
- copy:需要遵守NSCopying协议,实现copyWithZone:方法,调用copy会自动实现copyWithZone:方法
- mutableCopy:需要遵守NSMutableCopying协议,实现mutableCopyWithZone:方法
浅复制和深复制
- 浅复制(浅拷贝,指针拷贝,shallowcopy)
- 源对象和副本对象是一个对象
- 源对象(副本对象)引用计数器+1,相当于做了一次retain操作
- 本质没有产生新的对象
- 深复制(深拷贝,内容拷贝,deep copy)
- 源对象和副本对象是不同的两个对象
- 源对象引用计数器不变,副本对象计数器为1(因为是新产生的)
- 本质是:产生了新的对象
- 浅复制(浅拷贝,指针拷贝,shallowcopy)
注意:只有源对象和副本对象都不可变时,才是浅复制,其它都是深复制
copy内存管理
- 浅拷贝,原对象引用计数器+1,必须对原对象进行释放
- 深拷贝,创建了新对象,必须对新对象释放
@property中的copy的作用
- 防止外界修改内部的值
- 防止访问对象已经释放
- 若是用copy修饰block代表将block移到堆内存中,那么一旦在block中访问了某个对象,就会对该对象进行一次retain操作
- 也可以使用Block_copy(myBlock);将block转移到堆中
- 注意:
- block默认存储在栈中,栈中的block对象访问了外界的对象,不会进行retain操作
- block如果在堆中,一旦block中访问了外界的对象,会对外界的对象进行一次retain操作,防止block在使用对象之前,对象就已经释放,造成内存泄漏
- 若是在block定义在一个类中,又在程序中访问了对象本身,那么为了避免内存泄漏想,需要将对象修饰为__block
自定义对象实现copy操作
- 让类遵守NSCopying或NSMutableCopying协议
- 实现copyWithZone:方法,在该方法中返回一个对象的副本即可
- 在copyWithZone方法中,创建一个新的对象,并设置该对象的数据与现有对象一致, 并返回该对象
- 无父类实现
-(id)copyWithZone(NSZone *)zone{
CustomMode *custom = [[[self class] copyWithZone:zone] init];
Custom.a = [_a copyWithZone:zone];
Custom.c = _c;//不是对象的 直接赋值
Return custom;
}
- 有父类实现
- 不调用父类方法, 无法拷贝父类中继承的属性
- 不重新调用父类copyWithZone,无法拷贝本来中的特有属性
-(id)copyWithZone(NSZone *)zone{
CustomModel *custom = [super copyWithZone:zone];
….
Return custom;
}
3. @property内存管理策略
- 非ARC
- copy : 只用于NSString\block
- retain : 除NSString\block以外的OC对象
- assign:基本数据类型、枚举、结构体(非OC对象),当2个对象相互引用,一端用retain,一端用assign
- ARC
- copy : 只用于NSString\block
- strong :除NSString\block以外的OC对象
- weak:当2个对象相互引用,一端用strong,一端用weak
- assgin:基本数据类型、枚举、结构体(非OC对象)