zoukankan      html  css  js  c++  java
  • ios数据存储——对象归档

    归档:数据从内存与闪存相互转化,类似“序列化”,将数据转换成二进制字节数据

    操作:有两种方式,第一种是单个对象作为root进行归档和恢复,一个对象一个文件;第二种,可以同时归档多个对象到一个文件

    注意:归档自定义对象,需要实现NSCoding协议里的两个方法,举例说明:【preference】http://blog.csdn.net/mad1989/article/details/9106475

    一、创建一个数据模型(自定义类)

    现在就以大家常见的Student的为例,这个模型有5个参数:name、age、weight、hobby、others

    Student.h

    [cpp] view plain copy
     
    1. #import <Foundation/Foundation.h>  
    2.   
    3. @interface Student : NSObject<NSCoding,NSCopying>  
    4.   
    5. @property(copy,nonatomic) NSString *name;  
    6. @property(assign,nonatomic) int age;  
    7. @property(assign,nonatomic) double  weight;  
    8. @property(copy,nonatomic) NSArray *hobby;  
    9. @property(copy,nonatomic) NSDictionary *others;  
    10.   
    11.   
    12.   
    13. @end  


    Student.m

    [cpp] view plain copy
     
    1. #import "Student.h"  
    2.   
    3.   
    4. #define knameKey @"name"  
    5. #define kageKey @"age"  
    6. #define kweightKey @"weight"  
    7. #define khobbyKey @"hobby"  
    8. #define kotherKey @"others"  
    9.   
    10. @implementation Student  
    11.   
    12. @synthesize name;  
    13. @synthesize age;  
    14. @synthesize weight;  
    15. @synthesize hobby;  
    16. @synthesize others;  
    17.   
    18.   
    19. #pragma mark-NSCoding  
    20. -(void)encodeWithCoder:(NSCoder *)aCoder{  
    21.   
    22.   
    23.     [aCoder encodeObject:name forKey:knameKey];  
    24.     [aCoder encodeInt:age forKey:kageKey];  
    25.     [aCoder encodeDouble:weight forKey:kweightKey];  
    26.     [aCoder encodeObject:hobby forKey:khobbyKey];  
    27.     [aCoder encodeObject:others forKey:kotherKey];  
    28.   
    29. }  
    30.   
    31.   
    32. -(id)initWithCoder:(NSCoder *)aDecoder{  
    33.       
    34.     if (self == [super init]) {  
    35.        name =  [aDecoder decodeObjectForKey:knameKey];  
    36.        age = [aDecoder decodeIntForKey:kageKey];  
    37.        weight =  [aDecoder decodeDoubleForKey:kweightKey];  
    38.        hobby =  [aDecoder decodeObjectForKey:khobbyKey];  
    39.        others =  [aDecoder decodeObjectForKey:kotherKey];  
    40.     }  
    41.       
    42.     return self;  
    43. }  
    44.   
    45.   
    46.   
    47. #pragma mark-NSCopying  
    48. -(id)copyWithZone:(NSZone *)zone{  
    49.     Student *copy = [[[self class] allocWithZone:zone] init];  
    50.     copy.name = [self.name copyWithZone:zone];  
    51.     copy.age = self.age;  
    52.     copy.weight = self.weight;  
    53.     copy.hobby = [self.hobby copyWithZone:zone];  
    54.     copy.others = [self.others copyWithZone:zone];  
    55.       
    56.     return copy;  
    57. }  
    58.   
    59.   
    60. @end  


    通过以上的代码我们可以看出,要实现对数据模型的归档,需要我们实现NScoding协议,NScoping(copy协议是为了模型数据可以复制,对于归档而言,不是必须要实现)

    NScoding协议需要实现两个方法:

    -(void)encodeWithCoder:(NSCoder *)aCoder    以keyValue形式对基本数据类型Encoding

    -(id)initWithCoder:(NSCoder *)aDecoder      以keyValue形式对基本数据类型Decoding,返回数据模型本身

     

    -(id)copyWithZone:(NSZone *)zone      NScopying协议的方法,目的为了实现数据模型的copy,如下实例:

     

    [cpp] view plain copy
     
    1. Student *s1 = [[Student alloc] init];  
    2. Student *s2 = [s1 copy];  
    3. NSLog(@"s1:%@",s1);  
    4. NSLog(@"s2:%@",s2);  

    Log控制台输出:

    2013-06-16 16:19:36.157 ArchiveDemo[1357:c07] s1:<Student: 0x8875340>

    2013-06-16 16:19:36.158 ArchiveDemo[1357:c07] s2:<Student: 0x8875360>



    二、ViewController.xib添加几个针对数据模型的可编辑组件:

    三、接下来就是在Viewcontroller.m中的操作,首先添加一个内部使用的方法,返回要保存到闪存的位置:

    [cpp] view plain copy
     
    1. -(NSString *) getFilePath{  
    2.   
    3.     NSArray *array =  NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
    4.       
    5.      return [[array objectAtIndex:0] stringByAppendingPathComponent:kFileName];  
    6.       
    7. }  



    在ViewDidLoad方法里,每次viewController初始化时,读取路径下的归档文件,读取数据模型数据。同时添加一个通知每当按下Home键时,数据及时归档到闪存中。

    [cpp] view plain copy
     
    1. - (void)viewDidLoad  
    2. {  
    3.     [super viewDidLoad];  
    4.       
    5.     if ([[NSFileManager defaultManager] fileExistsAtPath:[self getFilePath]]) {  
    6.         NSLog(@"filePAth:%@",[self getFilePath]);  
    7.           
    8.         NSData *data = [[NSData alloc] initWithContentsOfFile:[self getFilePath]];  
    9.           
    10.         NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];  
    11.           
    12.         //解档出数据模型Student  
    13.         Student *mStudent = [unarchiver decodeObjectForKey:kDataKey];  
    14.         [unarchiver finishDecoding];//一定不要忘记finishDecoding,否则会报错  
    15.    
    16.         //接档后就可以直接使用了(赋值到相应的组件属性上)  
    17.         self.nameLabel.text = mStudent.name;  
    18.         self.ageLabel.text = [NSString stringWithFormat:@"%d",mStudent.age];  
    19.         self.weightLabel.text = [NSString stringWithFormat:@"%f",mStudent.weight];  
    20.         self.hobbyTextField.text = [mStudent.hobby objectAtIndex:0];  
    21.         self.othersTextView.text = [mStudent.others objectForKey:@"other"];  
    22.           
    23.         [unarchiver release];  
    24.         [data release];  
    25.     }  
    26.       
    27.     //添加一个广播,用于注册当用户按下home键时,归档数据到闪存中  
    28.     UIApplication *app = [UIApplication sharedApplication];  
    29.     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveAppDataWhenApplicationWillResignActive) name:UIApplicationWillResignActiveNotification object:app];  
    30.       
    31. }  



    四、某一操作需要保存数据的时候,及时归档到闪存中

    [cpp] view plain copy
     
    1. /** 
    2.  *当用户按下Home键,返回桌面时,归档当前数据到指定文件路径下 
    3.  */  
    4. -(void) saveAppDataWhenApplicationWillResignActive:(NSNotification*) notification{  
    5.       
    6.     Student *saveStudent = [[Student alloc] init];  
    7.     saveStudent.name = self.nameLabel.text;  
    8.     saveStudent.age = [self.ageLabel.text intValue];  
    9.     saveStudent.weight = [self.weightLabel.text doubleValue];  
    10.     saveStudent.hobby = [NSArray arrayWithObjects:self.hobbyTextField.text, nil];  
    11.     saveStudent.others = [NSDictionary dictionaryWithObjectsAndKeys:self.othersTextView.text,@"other",nil];  
    12.       
    13.     NSMutableData *data = [[NSMutableData alloc] init];  
    14.       
    15.     NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];  
    16.       
    17.     [archiver encodeObject:saveStudent forKey:kDataKey];  
    18.       
    19.     [archiver finishEncoding];  
    20.       
    21.     [data writeToFile:[self getFilePath] atomically:YES];  
    22.     [data release];  
    23.     [archiver release];  
    24.     [saveStudent release];  
    25.       
    26.   
    27. }  



    运行效果:

    重新运行后:

    归档这种保存方式缺点就是没有属性列表(NSuserDefault)速度快,因为它每次都要把文件保存到闪存中,优点是可以创建自己想要的数据模型,然后统一以模型方式存储,比属性列表要过分依赖Key要省心。

  • 相关阅读:
    Luogu3118:[USACO15JAN]Moovie Mooving
    Luogu4137:Rmq Problem/mex
    Luogu3092:[USACO13NOV]No Change
    BZOJ4321: queue2
    BZOJ4650 : [NOI2016]优秀的拆分
    webpack
    sublime eslint setup
    Sublime themes/ lint themes setup
    sublime text 3
    React
  • 原文地址:https://www.cnblogs.com/lucky-star-star/p/5711306.html
Copyright © 2011-2022 走看看