复制对象:源对象和副本对象是两块不同的内存区域。
对象具备复制功能,必须实现
1):<NSCopying>协议
2):<NSMutableCopying>协议
3):常用的可复制对象有:NSNumber,NSString,NSArray,NSDictionary,NSMutableDictionary,NSMutableArray,NSMutableString.
复制对象的种类
1):copy:产生对象的副本是不可变的
2):mutableCopy:产生的对象副本是可变的
深浅复制的基本概念
1)浅复制只复制对象的本身,对象里的属性、包含的对象不做复制。
2)深复制则既复制对象本身,对象的属性也会复制一份。
3)Foundation框架中支持复制的类,默认是浅复制。
[浅复制指向同一块内存,深复制指向两块独立的内存]。
对象的自定义拷贝
对象拥有复制特性,须实现NSCopying、NSMutableCopying协议的
copyWithZone:方法和MutableCopyWithZone:方法。
- (id)copyWithZone:(NSZone *)zone {
User *user = [[[self class] allocWithZone:zone]init];
user.data = _data;
return user;
}//返回的是不可变对象
- (id)mutableCopyWithZone:(NSZone *)zone {
UserMutable *user = [[[self class] allocWithZone:zone]init];
user.data = _data;
return user;
}//返回的是可变对象。
Objective-C对象的深、浅拷贝的区别就在于你对copyWithZone:方法的不同实现
- (id)copyWithZone:(NSZone *)zone {
//浅复制的实现
Person *p = [[[self class] allocWithZone:zone]init];
p.name = _name;
p.age = _age;
return p;
//深复制的实现
Person *p = [[[self class] allocWithZone:zone]init];
p.name = [_name copy];
p.age = [_age copy];
return p;
}
深、浅拷贝和RETAIN之间的总结
copy、mutableCopy和retain之间的关系
1):Foundation可复制的对象,当我们copy的是一个不可变的对象时,它的作用相当于是retain(cocoa做的内存优化)。 [不可变的对象调用copy相当于retain.]
2):当我们使用mutableCopy时,无论源对象是否可变,副本是可变的,并且实现了真正意义上的拷贝。
1):概念:对象归档是指将对象写入文件保存在硬盘上,当再次重新打开程序时,可以还原这些对象。你也可以称它为对象序列化、对象持久。
2):数据持久化的方式
a.NSKeyedArchiver—对象归档
b. NSUerDefaults
c.属性列表化(NSArray、NSDictionary保存文件)
d. SQlite数据库、CoreData数据库
3):归档的形式
a.对Foundation库中对象进行归档
b.自定义对象进行归档(需要实现归档协议,NSCoding)
4):归档后的文件是加密的,属性列表是明文的
属性列表里只能加入Foundation中自带的类型,而自定义类型不可以加入。
/***********************第一种归档方式*********************/
/**归档对象**/
// NSArray *array = @[@"abc",@"123",@1234];
// NSString *homePath = NSHomeDirectory();
// NSString *path = [homePath stringByAppendingPathComponent:@"test.abc"];
// BOOL success = [NSKeyedArchiver archiveRootObject:array toFile:path];
// if(success)
{
// NSLog(@"archive success!");
// }
/**解归档**/
NSString *homePath = NSHomeDirectory();
NSString *path = [homePath stringByAppendingPathComponent:@"test.abc"];
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
NSLog(@"%@",array);
自定义内容归档
归档
1):使用NSData实例作为归档的存储数据
2):添加归档的内容(设置key与value)
3):完成归档
4):将归档数据存入磁盘中
解归档
1):从磁盘读取文件,生成NSData实例
2):根据Data实例创建和初始化解归档实例
3):解归档,根据key访问value的值。
/***********************第二种归档方式*********************/
// NSString *homePath = NSHomeDirectory();
// NSString *path = [homePath stringByAppendingPathComponent:@"archiver2.arc"];
// NSMutableData *data = [NSMutableData data];
// NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
// NSArray *array = @[@"jack",@"tom"];
// [archiver encodeInt:100 forKey:@"age"];
// [archiver encodeObject:array forKey:@"names"];
// [archiver finishEncoding];
// [archiver release];
// BOOL success = [data writeToFile:path atomically:YES];
// if (success) {
// NSLog(@"archive success!");
// }
/**解归档**/
NSString *homePath = NSHomeDirectory();
NSString *path = [homePath stringByAppendingPathComponent:@"archiver2.arc"];
NSData *data = [NSData dataWithContentsOfFile:path];
NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
int age = [unArchiver decodeIntForKey:@"age"];
NSArray *names = [unArchiver decodeObjectForKey:@"names"];
[unArchiver release];
NSLog(@"age = %d,names = %@",age,names);
自定义对象的归档基本概念
1.自定义的对象要支持归档,需要实现NSCoding协议。
2. NSCoding协议有两个方法,encodeWithCoder方法对对象的属性数据做编码处理。initWithCoder解码归档数据来初始化对象。
3.实现NSCoding协议后,就能通过NSKeyedArchiver归档。
**********************************************************
详细解释:copy其实是建立了一个相同的对象,而retain不是。比如一个NSString对象,地址为0x1111,内容为@“str”,copy到另外一个NSString之后,地址为0x2222,内容相同,新的对象retain为1,旧的对象没有变化。retain到另一个NSString之后,地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1,也就是说,retain是指针拷贝,copy是内容拷贝,在拷贝之前,都会释放旧的对象。
assign:简单赋值,不更改索引计数。
copy:建立一个索引计数为1的对象,然后释放旧对象。
retain:释放旧对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1。
使用assign:对基础数据类型(NSInteger)和C数据类型(int,float,double,char等)
使用copy: 对NSString
使用retain:对其他NSObject和其子类。
/***********************自定义对象的归档*********************/
// User *user = [[User alloc]init];
// user.name = @"jack";
// user.age = 22;
// user.email = @"skewrain@foxmail.com";
// user.password = @"123455";
// NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"skewrain.abc"];
// BOOL success = [NSKeyedArchiver archiveRootObject:user toFile:path];
// if (success) {
// NSLog(@"archived success!");
// }
// [user release];
/****自定义对象解归档****/
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"skewrain.abc"];
User *user = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
NSLog(@"%@",user);
对象具备复制功能,必须实现
1):<NSCopying>协议
2):<NSMutableCopying>协议
3):常用的可复制对象有:NSNumber,NSString,NSArray,NSDictionary,NSMutableDictionary,NSMutableArray,NSMutableString.
复制对象的种类
1):copy:产生对象的副本是不可变的
2):mutableCopy:产生的对象副本是可变的
copy和retain的区别:
retain的复制指的是指向同一块内存。copy的复制指的是新复制一个对象,两个对象是独立的。
深浅复制的基本概念
1)浅复制只复制对象的本身,对象里的属性、包含的对象不做复制。
2)深复制则既复制对象本身,对象的属性也会复制一份。
3)Foundation框架中支持复制的类,默认是浅复制。
[浅复制指向同一块内存,深复制指向两块独立的内存]。
对象的自定义拷贝
对象拥有复制特性,须实现NSCopying、NSMutableCopying协议的
copyWithZone:方法和MutableCopyWithZone:方法。
- (id)copyWithZone:(NSZone *)zone {
User *user = [[[self class] allocWithZone:zone]init];
user.data = _data;
return user;
}//返回的是不可变对象
- (id)mutableCopyWithZone:(NSZone *)zone {
UserMutable *user = [[[self class] allocWithZone:zone]init];
user.data = _data;
return user;
}//返回的是可变对象。
Objective-C对象的深、浅拷贝的区别就在于你对copyWithZone:方法的不同实现
- (id)copyWithZone:(NSZone *)zone {
//浅复制的实现
Person *p = [[[self class] allocWithZone:zone]init];
p.name = _name;
p.age = _age;
return p;
//深复制的实现
Person *p = [[[self class] allocWithZone:zone]init];
p.name = [_name copy];
p.age = [_age copy];
return p;
}
深、浅拷贝和RETAIN之间的总结
copy、mutableCopy和retain之间的关系
1):Foundation可复制的对象,当我们copy的是一个不可变的对象时,它的作用相当于是retain(cocoa做的内存优化)。 [不可变的对象调用copy相当于retain.]
2):当我们使用mutableCopy时,无论源对象是否可变,副本是可变的,并且实现了真正意义上的拷贝。
3):当我们copy的是一个可变对象时,副本对象是不可变,同样实现了真正意义上的拷贝。
1):概念:对象归档是指将对象写入文件保存在硬盘上,当再次重新打开程序时,可以还原这些对象。你也可以称它为对象序列化、对象持久。
2):数据持久化的方式
a.NSKeyedArchiver—对象归档
b. NSUerDefaults
c.属性列表化(NSArray、NSDictionary保存文件)
d. SQlite数据库、CoreData数据库
3):归档的形式
a.对Foundation库中对象进行归档
b.自定义对象进行归档(需要实现归档协议,NSCoding)
4):归档后的文件是加密的,属性列表是明文的
属性列表里只能加入Foundation中自带的类型,而自定义类型不可以加入。
/***********************第一种归档方式*********************/
/**归档对象**/
// NSArray *array = @[@"abc",@"123",@1234];
// NSString *homePath = NSHomeDirectory();
// NSString *path = [homePath stringByAppendingPathComponent:@"test.abc"];
// BOOL success = [NSKeyedArchiver archiveRootObject:array toFile:path];
// if(success)
{
// NSLog(@"archive success!");
// }
/**解归档**/
NSString *homePath = NSHomeDirectory();
NSString *path = [homePath stringByAppendingPathComponent:@"test.abc"];
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
NSLog(@"%@",array);
自定义内容归档
归档
1):使用NSData实例作为归档的存储数据
2):添加归档的内容(设置key与value)
3):完成归档
4):将归档数据存入磁盘中
解归档
1):从磁盘读取文件,生成NSData实例
2):根据Data实例创建和初始化解归档实例
3):解归档,根据key访问value的值。
/***********************第二种归档方式*********************/
// NSString *homePath = NSHomeDirectory();
// NSString *path = [homePath stringByAppendingPathComponent:@"archiver2.arc"];
// NSMutableData *data = [NSMutableData data];
// NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
// NSArray *array = @[@"jack",@"tom"];
// [archiver encodeInt:100 forKey:@"age"];
// [archiver encodeObject:array forKey:@"names"];
// [archiver finishEncoding];
// [archiver release];
// BOOL success = [data writeToFile:path atomically:YES];
// if (success) {
// NSLog(@"archive success!");
// }
/**解归档**/
NSString *homePath = NSHomeDirectory();
NSString *path = [homePath stringByAppendingPathComponent:@"archiver2.arc"];
NSData *data = [NSData dataWithContentsOfFile:path];
NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
int age = [unArchiver decodeIntForKey:@"age"];
NSArray *names = [unArchiver decodeObjectForKey:@"names"];
[unArchiver release];
NSLog(@"age = %d,names = %@",age,names);
自定义对象的归档基本概念
1.自定义的对象要支持归档,需要实现NSCoding协议。
2. NSCoding协议有两个方法,encodeWithCoder方法对对象的属性数据做编码处理。initWithCoder解码归档数据来初始化对象。
3.实现NSCoding协议后,就能通过NSKeyedArchiver归档。
**********************************************************
详细解释:copy其实是建立了一个相同的对象,而retain不是。比如一个NSString对象,地址为0x1111,内容为@“str”,copy到另外一个NSString之后,地址为0x2222,内容相同,新的对象retain为1,旧的对象没有变化。retain到另一个NSString之后,地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1,也就是说,retain是指针拷贝,copy是内容拷贝,在拷贝之前,都会释放旧的对象。
assign:简单赋值,不更改索引计数。
copy:建立一个索引计数为1的对象,然后释放旧对象。
retain:释放旧对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1。
使用assign:对基础数据类型(NSInteger)和C数据类型(int,float,double,char等)
使用copy: 对NSString
使用retain:对其他NSObject和其子类。
/***********************自定义对象的归档*********************/
// User *user = [[User alloc]init];
// user.name = @"jack";
// user.age = 22;
// user.email = @"skewrain@foxmail.com";
// user.password = @"123455";
// NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"skewrain.abc"];
// BOOL success = [NSKeyedArchiver archiveRootObject:user toFile:path];
// if (success) {
// NSLog(@"archived success!");
// }
// [user release];
/****自定义对象解归档****/
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"skewrain.abc"];
User *user = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
NSLog(@"%@",user);