iOS数据持久化

============================= 演示数据的读、写。通过"plist文件"来存储 =============================

    * 介绍"沙盒路径" "Bundle 路径"

    ** /Users/...../Data/... 这个是沙盒路径

    ** /Users/...../Bundle/.... 这个是 Bundle 路径



    * 介绍"沙盒"下的目录结构

    1> Documents目录: 保存应用程序自己的数据(比如:游戏进度存档、软件的一些个人设置等)。通过 iTunesiCloud 备份时, 会备份这个目录下的数据


    2> Tmp 目录: 存储一些其他临时数据, 系统磁盘空间不够, 手机重启时, 会自动清除这个目录的数据。无需程序员手动清除该目录中的数据.iTunesiCloud 备份时, 不会备份这个目录下的数据。


    3> Caches 目录: 保存从网络上下载的文件(比如:听歌时的缓存、图片的缓存等),这个目录下的数据不会被自动删除,需要程序员自己实现清除目录数据功能。iTunesiCloud 备份时, 不会备份这个目录下的数据。


    4> Preference目录: 保存通过"偏好设置"写入的数据。iTunesiCloud 备份时, 会备份这个目录下的数据。



    * "沙盒" -> "Sandbox"


    * "沙盒"示例路径: /Users/Steve/Library/Developer/CoreSimulator/Devices/0C63A035-071E-4EFC-8718-C387A3F7E026/data/Containers/Data/Application/287DAF0F-B201-4EDA-9E8A-D1DEDD9C9135


    * 通过调用NSHomeDirectory();来获取沙盒的根目录。

    NSString *sandboxPath = NSHomeDirectory();


    * 获取"沙盒"下的"Documents"的路径

    1> 方式一: 先获取"沙盒"根路径, 再获取Documents路径(拼接)。(不推荐, 因为一旦系统升级Documents目录名字变了就不能用了)

    NSString *sandboxPath = NSHomeDirectory();

    NSString *docPath = [sandboxPath stringByAppendingPathComponent:@"Documents"];


    2> 方式二:

    /** 参考代码:

     

     // NSUserDomainMask 代表从用户文件夹下找, 沙盒根路径。

     // YES 代表展开路径中的波浪字符“~”

     NSArray *array =  NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

     

     // iOS中,只有一个目录跟传入的参数匹配(沙盒中只有一个Documents目录),所以这个集合里面只有一个元素

     NSString *documents = [array objectAtIndex:0];

     

     NSLog(@"%@", documents);

     

     */


    * "沙盒"中写入数据

    NSArray *array = @[@"Bob", @"John", @"Steve"];

    NSString *filePath = [docPath stringByAppendingPathComponent:@"data.plist"];

    [array writeToFile:filePath atomically:YES];




    * "沙盒"中读取数据

    1> 获取文件的路径


    2> 调用NSArrayNSDictionaryxxxWithContentsOfFile


    ** 总结: 使用对象: 仅仅是Foundation框架中的一些类, 比如: NSString\NSArray\NSDictionary\NSSet\NSNumber\NSData


    ** 总结: 调用对象的writeToFile \ xxxWithContentsOfFile 方法来实现。

============================= 演示数据的读、写。通过"plist文件"来存储 =============================





============================= 演示数据的读、写。通过"Preference(偏好设置)"来存储。 =============================


    * 使用"偏好设置"来存储数据, 本质上就是通过"plist"来存储数据, 但是使用起来更简单(无需关注文件、文件夹路径和名称)


    * 通过"偏好设置"的方式读、写文件时, 路径在"沙盒根目录" -> "Library" -> "Preferences"


    * 使用步骤:

    1> 创建一个访问"偏好设置"目录的对象NSUserDefaults对象

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; // 获得单例对象


    2> 通过"键值对"方式存储数据

    [defaults setObject:@"value" forKey:@"key"];

    [defaults setInteger:100 forKey:@"age"];

    [defaults setBool:YES forKey:@"auto_login"];


    3> 同步, 将内存中的数据写入文件。

    [defaults synchronize];


    ** 注意: 如果不调用synchronize方法, 则由系统随机进行同步(什么时候同步不确定)


    4> "偏好设置"中读取数据

    [defaults objectForKey:@"key"];

    [defaults boolForKey:@"key"];


    ** 使用"偏好设置"存储数据的不足: 数据只能存储在一个文件中, 不存储大批量数据(很多时候大批量数据要分多个文件存储)

============================= 演示数据的读、写。通过"Preference(偏好设置)"来存储。 =============================







============================= 演示数据的读、写。通过"归档"的方式来存储。对象必须遵守NSCoding协议。 =============================

    * 通过"plist"文件来保存数据, 无法直接将一个对象保存到文件中。比如Person对象就没有writeToFile方法。


    * "归档"是一种可以把任何对象, 直接保存为文件的方式。(其中包括"归档""反归档(读档)")


    * 归档: 对象 -> 文件

    [NSKeyedArchiver archiveRootObject:person toFile:filePath];


    * 反归档(读档): 文件 -> 对象

    [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];


    * 通过"归档"的方式能将任何遵守了NSCoding协议的"对象"存储到文件中


    * NSCoding协议的两个重要的方法:

    1> - (void)encodeWithCoder:(NSCoder *)aCoder;

        /**

             ** 作用: 对象归档时调用该方法(将对象写入文件时).

             1> 说明哪些属性要存储

             

             2> 说明如何存储这些属性

             

             ** 示例代码:

             // 归档时调用该方法

             - (void)encodeWithCoder:(NSCoder *)aCoder

             {

                 [aCoder encodeObject:self.name forKey:@"name"];

                 [aCoder encodeInteger:self.age forKey:@"age"];

                 [aCoder encodeDouble:self.height forKey:@"height"];

             }

             

             // 通过调用NSKeyedArchiverarchiveRootObject方法来实现归档

             CZPerson *person = [[SteveZPerson alloc] init];

             person.name = @"JackMeng";

             person.age = 27;

             person.height = 1.75;

             

             // 获取沙盒路径

             NSString *sandBoxPath = NSHomeDirectory();

             // 获取Documents的路径

             NSString *docPath = [sandBoxPath stringByAppendingPathComponent:@"Documents"];

             // 获取文件路径

             NSString *filePath = [docPath stringByAppendingPathComponent:@"person.plist"];

             

             // 将对象person归档

             [NSKeyedArchiver archiveRootObject:person toFile:filePath];

         */



    2> - (id)initWithCoder:(NSCoder *)aDecoder;

        /**

             ** 作用: 当从文件中解析对象时调用该方法.

             1> 说明哪些属性要解析(读取)

             

             2> 说明如何解析(读取)这些属性

             

             ** 示例代码:

             

             // 读档时调用该方法

             - (id)initWithCoder:(NSCoder *)aDecoder

             {

                 if (self = [super init]) {

                 self.name = [aDecoder decodeObjectForKey:@"name"];

                 self.age = [aDecoder decodeIntegerForKey:@"age"];

                 self.height = [aDecoder decodeDoubleForKey:@"height"];

             }

                return self;

             }

             

             // 获取沙盒路径

             NSString *sandBoxPath = NSHomeDirectory();

             // 获取Documents的路径

             NSString *docPath = [sandBoxPath stringByAppendingPathComponent:@"Documents"];

             // 获取文件路径

             NSString *filePath = [docPath stringByAppendingPathComponent:@"person.bin"];

             

             CZPerson *person = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];

             

             NSLog(@"name: %@, age: %ld, height: %f", person.name, person.age, person.height);

         

         */



    * 如果父类中也有属性需要归档、读档, 在子类中必须调用super的相关方法。

    /**

     示例代码:

     @implementation SteveZStudent

         - (id)initWithCoder:(NSCoder *)aDecoder

         {

             if (self = [super initWithCoder:aDecoder]) {

                self.SNo = [aDecoder decodeObjectForKey:@"SNo"];

             }

             return self;

         }

         

         - (void)encodeWithCoder:(NSCoder *)aCoder

         {

             [super encodeWithCoder:aCoder];

             [aCoder encodeObject:self.SNo forKey:@"SNo"];

         }

     @end

     */


============================= 演示数据的读、写。通过"归档"的方式来存储。对象必须遵守NSCoding协议。 =============================







***** 使用SQLite数据库存储, 当非常大量的数据存储时使用 *****

***** 使用Core Data存储, 就是对SQLite的封装 *****

1> iOS 5.0出现

2> 效率低下, 不需要懂SQL语句, 直接操作对象。


***** 使用Core Data存储, 就是对SQLite的封装 *****

***** 通过"网络"方式存储 *****

你可能感兴趣的:(iOS数据持久化)