-----------android培训、java培训、java学习型技术博客、期待与您交流!-----------
OC中集合对象的内存管理及copy的用法
一、集合对象的内存管理
官方原则:
1、当调用alloc、new、copy(mutablecopy)方法产生一个新对象的时候,就必须在最后调用一次release 或者autorelease
2、当调用retain 方法让对象的计数器+1,就必须在最后调用一次release 或者autorelease
集合的内存管理原则细节
1、当把 一个对象添加到集合中时,这个对象会做一次retain 操作,计数器+1
2、当一个集合被销毁时,会对集合里面的每一个元素执行一次release 操作,计数器会 -1
3、当一个对象从集合中移除,这个对象会执行一次release操作,计数器会 -1
普遍规律:
1、如果方法名是以add/insert开头,那么被添加的对象,计数器会 +1
2、如果方法名是以remove/delete 开头,那么被移除的对象,计数器 -1
二、copy概念 及特点
Copy是复制,拷贝的意思,是一哥产生副本对象的过程
目的:使用某个对象的数据,但是在修改对象的时候不影响原来的对象内容
特点:修改源(对象)文件,不影响副本(对象)文件;修改副本(对象)文件,不影响源(对象)文件
三、copy的使用及条件
一个对象可以调用copy和mutableCopy方法来创建一个副本对象
copy:创建的是一个不可变的副本
mutableCopy:创建的是可变的副本
四、使用copy功能的前提
copy :需要遵守NSCopying 协议,实现copyWithZone:方法
@protocol NSCopying
-(id) copyWithZone: (NSZone *)zone;
@end
mutableCopy;需要遵守NSmutableCopying协议,实现mutableCopyWithZone:方法
@protocol NSMUtableCopying
-(id) mutableCopyingWithZone: (NSZone *) zone;
@end
五、copy与内存管理
copy 是浅拷贝
1、没有产生新的对象,没有重新分配空间
2、只是拷贝了对象的地址,源对象和副本对象是同一个对象
3、副本对象指针指向了储存在常量区的原对象,
4、源对象的引用计数 +1,副本对象引用 计数器也增加,相当于做了一次retain
5、本质:没有产生新的对象
mutableCopy 是深拷贝
1、在内存中重写分配一块内存空间存储副本对象,
2、在内存空间中是两块地址,源对象和副本对象是两个不同的对象
3、源对象引用计数器不变,拷贝完成后副本的应用计数为 1
4、本质:产生了新的对象
六、@property中copy的作用
@property 内存管理策略的选择
1、非ARC
(1)copy:只用于NSString / block
(2)retain :除NSString /block 以外的OC对象
(3)assign :基本数据类型、枚举、结构体(非结OC对象),当两个对象相互引用时,一端使用retain,另一端使用assgin
2、ARC
(1)copy:只用于NSString/block
(2)strong :除NSString /block 以外的OC对象
(3)weak:当两个对象相互引用时,一段使用strong,一段使用weak
(4)assgin:基本数据类型、枚举、结构体(非OC对象)
七、在自定义类中实现copy
在自定义类中实现copy的步骤
1、让这个类遵守NSCopying协议
2、实现copyWithZone:方法,在该方法中返回一个对象的副本
3、在copyWithZone方法中,创建一个新的对象,并设置该对象的数据与现有对象一致,并返回该对象
4、创建对象,调用copy方法,查看地址
为自定义的类实现copy操作
#import <Foundation/Foundation.h>
//遵守NSCopying协议
@interface Dog:NSObject <NSCopying>
@property (nonatomic , assign) int tuiNum;
@property (nonatomic , assign) int speed;
@end
@implementation Dog
-(id) copyWithZone:(NSZone *)zone{
Dog *d = [ [Dog alloc] init ] ;
d.speed = self.speed;
d.tuiNum = self.tuiNum;
return d;
}
@end
//主函数
int main (){
@autoreleasepool{
Dog *jd = [Dog new];
jd .speed = 230;
jd . tuiNum = 8;
//实现对象的拷贝,所有自定义方法中的copy都是深拷贝
Dog *byd = [jd copy];
NSLog(@"%d, %d" , byd.speed, byd.tuiNum);
}
}