ios数据持久化

作者: Patrick_p | 来源:发表于2017-02-16 16:09 被阅读0次

    关于数据持久化

    数据持久化,字面上的意思来理解,就是将数据存放更长时间。
    很显然的,当我们在平时开发中,必然而然的会使用到数据的持久化,但是通用的几种方式,我们应该了然于心。以便于在使用到的时候,能够更好的选择使用哪一种。

    通常数据持久化的几种方式

    1.NSUserDefaults
    2.NSKeyedArchiver(对象模型归档)
    3.SQLite
    4.Core Data

    1.NSUserDefaults

    NSUserDefaults是苹果提供的一种偏好设置的方法,将我们需要的一些偏好设置写道plist文件当中。例如,记录主题设置的模式,是否自动登录等等。
    NSUserDefaults是苹果提供的一个单例,使用方法很简单,如下:

    ////write
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:@"daytime" forKey:@"themeStyle"];
    [defaults synchronize];
    
    
    ////read
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *themeStyle= [defaults objectForKey:@"themeStyle"]
    
    

    类似于此,NSUserDefaults 还持支NSData,NSString,NSNumber,NSDate,NSArray,NSDictionary这些数据类型。
    当然苹果还提供了具体类型的读写方法:

    - setBool:forKey:
    - setFloat:forKey:
    ...等
    

    但是,写数据的时候特别注意的是这一句话

    [defaults synchronize];
    

    当我们利用NSUserDefaults 来写入数据的时候,系统默认并不是马上就会写道plist里面,但是往往我们需要存一些偏好设置的时候,想法是写进去,plist里面就会马上响应,就可以马上读出来。如果想实现该需求,就需要在我们存储数据的最后面加上synchronize来同步数据到pilst里面。

    2.NSKeyedArchiver与沙盒

    NSKeyedArchiver 对象归档,就是当我们需要将自定义的类对象进行二进制化归档。而沙盒存储呢,简单的来说,就是将文件给存到本地磁盘中。

    NSKeyedArchiver

    首先,要使用NSKeyedArchiver归档,就需要实现NSCoding协议。同时实现其序列化和反序列化这两个方法

    //反序列化
    //从coder中读取数据,保存到相应的变量中
    - (id)initWithCoder:(NSCoder *)aDecoder;
    
    // 序列化
    //读取实例变量,并把这些数据写到coder中。
    -(void)encodeWithCoder:(NSCoder *)coder;
    

    沙盒

    关于ios沙盒机制,简单来说就是一个安全权限。默认权限下,苹果只允许IOS应用程序访问程序自己的目录,该目录就称为“沙盒”。
    下图是沙河目录

    MyApp.app

    存放应用程序本身的数据,整个目录是只读的
    不会被iTunes同步

    Documents

    存放应用程序的数据文件(不可再生的)
    会被iTunes同步

    Documents/Inbox

    存放保存由外部应用请求当前应用程序打开的文件
    会被同步

    Library

    苹果建议用来存放默认设置或其它状态信息
    会被iTunes同步,但是除了Caches子目录

    Library/Caches

    主要是缓存文件
    不会被iTunes同步

    Library/Preferences

    应用程序的偏好设置文件。例如NSUserDefaults写的设置数据都会保存到该目录下的一个plist文件中
    会被iTunes同步

    tmp

    各种临时文件,保存应用再次启动时不需要的文件,并且随时有可能被系统清理掉
    不会被iTunes同步

    简单的使用

    了解了NSKeyedArchiver需要什么,沙盒是什么了,下面我们就开始来看代码:

    @interface Person: NSObject <NSCoding>
    @property (nonatomic, strong) NSString *name;
    @property (nonatomic, strong) NSString *sex;
    @end
    
    //...
    //实现序列化和反序列化
    @implementation Person
    
    - (void)encodeWithCoder:(NSCoder *)aCoder
    {
        [aCoder encodeObject:self.name forKey:@"name"];
        [aCoder encodeObject:self.sex forKey:@"sex"];
        
    }
    - (id)initWithCoder:(NSCoder *)aDecoder
    {
        self.name = [aDecoder decodeObjectForKey:@"name"];
        self.sex= [aDecoder decodeObjectForKey:@"sex"];
        
        return self;
    }
    
    @end
    
    
    Person* person=  [[Person alloc] init];
    person.name = @"zhu";
    person.age = @"man";
    ];
    //归档,调用encodeWithCoder方法 
    NSData * perData= [NSKeyedArchiver archivedDataWithRootObject:person];
    //读取归档数据,调用initWithCoder
    Person* per= [NSKeyedUnarchiver unarchiveObjectWithData:perData];
    
    
    //也可以将序列化的对象保存到沙盒中
     //获得Document的路径  
    NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];  
    //拓展名可以自己随便取
    NSString *path = [documents stringByAppendingPathComponent:@"person.archiver"];   
    [NSKeyedArchiver archiveRootObject:person toFile:path]; 
    
    //读取沙盒中的文件
    NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];  
    NSString *path = [documents stringByAppendingPathComponent:@"person.archiver"];  
    person *person1 = [NSKeyedUnarchiver unarchiveObjectWithFile:path];  
    
    
    

    3.SQLite

    SQLite是一个轻量级关系数据库,最初的设计目标是用于嵌入式系统,它占用资源非常少.在iOS中,只需要加入li’blibsqlite3.0依赖以及引入sqlite3.h头文件即可。
    关于sqlite在ios中的使用,我并没有深入的了解过,所以这里只是简单的介绍下。

    4.Core Data

    Core Data是iOS5之后才出现的一个框架,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象。
    至于到底是用coredata还是sqlite,大家是各持己见,但是我觉得还是应该看具体的业务逻辑。不要局限于某一个工具,而是在合适的时候选择合适的方法就好。
    关于coredata我们要知道的几个东西

    1.NSManagedObjectContext(托管对象上下文)
    负责应用和数据库之间的交互,例如增删查改。

    2.NSManagedObjectModel(托管对象模型)
    负责coredara里面的模型文件

    3.NSPersistentStoreCoordinator(持久化存储协调器)
    负责添加持久性数据库,例如sqlite,Binary、XML、或In-Memory等。但要注意这点,Binary和XML格式的存储区是Atomic,意思是就算我们只想修改少量的数据,但是在保存的时候还是得将整个文件都写进磁盘。

    对于coredata,初学者不要觉得很神奇,简单的想成是一个对象关系的数据库就行了,不需要写sql语句,就能实现数据的存取。
    下面是一些简单的使用:

    - (IBAction)addClick:(id)sender {
        
        NSLog(@"addClick");
       
        Employee *em = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:self.ctx];
        em.name = @"lisi";
        em.height = @172;
        em.age = @25;
        
        NSError *error = nil;
        [self.ctx save:&error];
        
        if (error) {
            NSLog(@"%@===error", error);
        } else {
            NSLog(@"=====add=success====");
        }
        
    }
    
    - (IBAction)readClick:(id)sender {
        
        NSLog(@"readClick");
        
        NSEntityDescription *enty = [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:self.ctx];
        NSFetchRequest *featch = [[NSFetchRequest alloc] init];
        
        [featch setEntity:enty];
        
    //    NSPredicate *pre = [NSPredicate predicateWithFormat:@"name=%@",@"lisi"];
    //    
    //    [featch setPredicate:pre];
        
        NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"height" ascending:YES];
        featch.sortDescriptors = @[sort];
        
        NSArray *arr = [self.ctx executeFetchRequest:featch error:nil];
        for (Employee *em in arr) {
            NSLog(@"姓名:%@ 身高%@",em.name ,em.height);
        }
    }
    
    
    - (IBAction)deleteClick:(id)sender {
        
        NSLog(@"deleteClick");
        
        NSEntityDescription *enty = [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:self.ctx];
        NSFetchRequest *featch = [[NSFetchRequest alloc] init];
        featch.entity = enty;
        featch.predicate = [NSPredicate predicateWithFormat:@"name=%@",@"lisi"];
        
        NSArray *arr = [self.ctx executeFetchRequest:featch error:nil ];   
        for (Employee *em in arr) {
            NSLog(@"姓名:%@ 身高%@",em.name ,em.height);
            [self.ctx deleteObject:em];
        }
        
        [self.ctx save:nil];
    }
    
    
    - (IBAction)updateClick:(id)sender {
        
        NSLog(@"updateClick");
        
        NSEntityDescription *enty = [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:self.ctx];
        NSFetchRequest *featch = [[NSFetchRequest alloc] init];
        featch.entity = enty;
        featch.predicate = [NSPredicate predicateWithFormat:@"name=%@",@"lisi"];
        
        NSArray *arr = [self.ctx executeFetchRequest:featch error:nil ];
        
        for (Employee *em in arr) {
            NSLog(@"姓名:%@ 身高%@",em.name ,em.height);
            em.name = @"wangwu";
        }
        
        [self.ctx save:nil];
    }
    
    - (NSManagedObjectContext *)ctx
    {
        if (!_ctx) {
            _ctx = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];        
                    
            NSManagedObjectModel *mModel = [NSManagedObjectModel mergedModelFromBundles:nil];
            
            NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mModel];
            
            NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
            NSString *url = [path stringByAppendingPathComponent:@"zhu.sqlite"];
            [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:url] options:nil error:nil];
            
            _ctx.persistentStoreCoordinator = coordinator;
        }
        return _ctx;
    }
    

    结束语

    其实关于ios中数据持久化的使用,不会仅限于此,以上只是一些简单的介绍和使用的方法。在当说到数据持久化的时候,我们脑海中应该蹦出一些自己的理解来。自己心中理一个适合自己的知识结构来帮助我们打理逻辑,然后在实际使用场景的时候,根据具体业务来选择具体使用哪一种数据持久化方案。我认为做开发的不要一脑门的死记硬背,一脑门的按照别人的说的来做。看到别人的逻辑的时候,觉得好的,自己心里领会下,觉得不好的,自己在想想怎么去做会更加完美。千万不要做代码的奴隶,而是以一种艺术家,建筑师又或者设计师的角度来审视代码。

    相关文章

      网友评论

        本文标题:ios数据持久化

        本文链接:https://www.haomeiwen.com/subject/nfwcwttx.html