OC视频笔记-对象的复制与归档

来源:互联网 发布:淘宝美工可以在家做吗 编辑:程序博客网 时间:2024/05/28 09:33
复制对象:源对象和副本对象是两块不同的内存区域。
对象具备复制功能,必须实现
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);

        
0 0
原创粉丝点击