IOS数据持久化总结

概论

所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据。在iOS开发中,常用的5种方案:

  • plist文件(属性列表)
  • preference(偏好设置)
  • NSKeyedArchiver(归档)
  • SQLite 3
  • CoreData
结构

沙盒就是一个文件夹,目录结构如下:

"应用程序包"
Documents
Library
    Caches
    Preferences
tmp
目录类型
  • "应用程序包": 这里面存放的是应用程序的源文件,包括资源文件和可执行文件。

      NSString *path = [[NSBundle mainBundle] bundlePath];
      NSLog(@"%@", path);
    
  • Documents: 最常用的目录,iTunes同步该应用时会同步此文件夹中的内容,适合存储重要数据。

      //第一种方法:
      NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
      //第二个参数 代表从用户文件夹下找, 第三个参数 代表是否显示路径全称,如果为no,那么输出为~/Documents/...
      NSLog(@"%@", path);
      
      //第二种方法: 
      //获取当前应用沙盒的根目录 
      NSString *homePath = NSHomeDirectory(); 
      //拼接路径 
      NSString *docPath = [homePath stringByAppendingPathComponent:@"Documents"];
    
  • Library/Caches: iTunes不会同步此文件夹,适合存储体积大,不需要备份的非重要数据。

      NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
      NSLog(@"%@", path);
    
  • Library/Preferences: iTunes同步该应用时会同步此文件夹中的内容,通常保存应用的设置信息。

      //NSUserDefaults存储的位置:
      //<UUID for your App>/Library/Preferences/<your App's bundle ID>.plist
    
  • tmp: iTunes不会同步此文件夹,系统可能在应用没运行时就删除该目录下的文件,所以此目录适合保存应用中的一些临时文件,用完就删除。

      NSString *path = NSTemporaryDirectory();
      NSLog(@"%@", path);
    
存储数据类型和存储方法
  • plist文件存取方式(位置任意)

属性列表是一种XML格式的文件,拓展名为plist,可以被序列化的类型只有如下几种:

存储时使用writeToFile: atomically:方法。 其中atomically表示是否需要先写入一个辅助文件,再把辅助文件拷贝到目标文件地址。这是更安全的写入文件方法,一般都写YES

  1. NSArray;

  2. NSMutableArray;

  3. NSDictionary;

  4. NSMutableDictionary;

  5. NSData;

  6. NSMutableData;

  7. NSString;

  8. NSMutableString;

  9. NSNumber;

  10. NSDate;

    //1.获得文件路径
    NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
    NSString *fileName = [path stringByAppendingPathComponent:@"123.plist"];
    
    //2.存储
    NSArray *array = @[@"123", @"456", @"789"];
    [array writeToFile:fileName atomically:YES];
    
    //3.读取
    NSArray *result = [NSArray arrayWithContentsOfFile:fileName];
    NSLog(@"%@", result);
    

有一点需要注意,就是存取字符串的时候,最好不要使用plist文件,因为plist本身不支持字符串(plist文件其根节点处,只有数组和字典两个选项),而且字符串的存取方法也已经过期。

  • 使用NSUserDefaults存储到Preference中(位置固定)

      //1.获得NSUserDefaults文件
      NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
      //2.向文件中写入内容
      [userDefaults setObject:@"AAA" forKey:@"a"];
      [userDefaults setBool:YES forKey:@"sex"];
      [userDefaults setInteger:21 forKey:@"age"];
      //2.1立即同步
      [userDefaults synchronize];
      //3.读取文件
      NSString *name = [userDefaults objectForKey:@"a"];
      BOOL sex = [userDefaults boolForKey:@"sex"];
      NSInteger age = [userDefaults integerForKey:@"age"];
      NSLog(@"%@, %d, %ld", name, sex, age);
    

注意:偏好设置是专门用来保存应用程序的配置信息的,一般不要在偏好设置中保存其他数据。如果没有调用synchronize方法,系统会根据I/O情况不定时刻地保存到文件中。所以如果需要立即写入文件的就必须调用synchronize方法。 偏好设置会将所有数据保存到同一个文件中。即preference目录下的一个以此应用包名来命名的plist文件。

* 使用NSKeyedArchiver归档存储(位置任意)

归档在iOS中是另一种形式的序列化,需要遵循NSCoding协议。

  1. 遵循NSCoding协议

     //1.遵循NSCoding协议
     @interface Person : NSObject  //2.设置属性
     @property (strong, nonatomic) UIImage *avatar;
     @property (copy, nonatomic) NSString *name;
     @property (assign, nonatomic) NSInteger age;
     @end
    
     //解档
     - (id)initWithCoder:(NSCoder *)aDecoder {
         if ([super init]) {
             self.avatar = [aDecoder decodeObjectForKey:@"avatar"];
             self.name = [aDecoder decodeObjectForKey:@"name"];
             self.age = [aDecoder decodeIntegerForKey:@"age"];
         }
         return self;
     }
     //归档
     - (void)encodeWithCoder:(NSCoder *)aCoder {
         [aCoder encodeObject:self.avatar forKey:@"avatar"];
         [aCoder encodeObject:self.name forKey:@"name"];
         [aCoder encodeInteger:self.age forKey:@"age"];
     }
    

特别注意:

如果需要归档的类是某个自定义类的子类时,就需要在归档和解档之前先实现父类的归档和解档方法。即 [super encodeWithCoder:aCoder] 和 [super initWithCoder:aDecoder] 方法;

  1. 用法

     //存
     NSString *file = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,      NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"person.data"];
     Person *person = [[Person alloc] init];
     person.avatar = self.avatarView.image;
     person.name = self.nameField.text;
     person.age = [self.ageField.text integerValue];
     [NSKeyedArchiver archiveRootObject:person toFile:file];
     
     //取
     NSString *file = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"person.data"];
     Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:file];
     if (person) {
         self.avatarView.image = person.avatar;
         self.nameField.text = person.name;
         self.ageField.text = [NSString stringWithFormat:@"%ld", person.age];
     }
    

注意:

  • 必须遵循并实现NSCoding协议
  • 保存文件的扩展名可以任意指定
  • 继承时必须先调用父类的归档解档方法
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 概论 所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据。在iOS开发中,...
    Leeson1989阅读 1,905评论 4 1
  • 作者:@翁呀伟呀 授权本站转载 概论 所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问...
    翻山越岭的另一边阅读 413评论 0 1
  • 醒来的时候,乔春还有点没睡醒,等摸着旁边发现没有摸到苏静,才清醒了一点。眯着眼睛挪到浴室,发现也没人,打开房门,竟...
    春少邪阅读 213评论 0 0
  • 听过一首歌 你是氯化钠 而我是氢氧脱氨酸 你是双曲线 我是渐近线 今年,你成婚待嫁 今年,我骑车海大 7年前,我们...
    文view阅读 275评论 0 0
  • 小时候,睡过午觉后醒来,常常能听到屋外叫卖着烧饼小吃的声音,差不多是三四点的光景,离晚饭还有段时间,人们在这个时候...
    yiyi_4f59阅读 198评论 0 0