iOS开发基础28-数据存储与沙盒机制

在iOS开发中,数据存储是非常重要的一环。本文将详细介绍iOS数据存储的常用方式,并对应用沙盒机制进行深入分析。

一、iOS应用数据存储的常用方式

1. XML属性列表(plist)归档

属性列表(Property List,简称plist)是一种用于存储简单结构化数据的XML格式文件。常用于存储数组、字典等基本数据类型。无法存储自定义对象。

2. Preference(偏好设置)

偏好设置是用于存储应用配置等简单数据的方式,使用NSUserDefaults类进行操作。它提供了一套标准的解决方案来保存和读取键值对数据,不需要关心具体存储文件的位置。

3. NSKeyedArchiver归档(NSCoding)

NSKeyedArchiver是一种将对象及其属性序列化为二进制数据,并将其写入文件的机制。通过实现NSCoding协议,可以归档和解档自定义对象。

4. SQLite3

SQLite3是一种轻量级关系数据库,适合存储结构化数据。可以通过C函数库进行操作,也可以使用第三方封装库(如FMDB)来简化操作。

5. Core Data

Core Data是iOS提供的对象图管理和持久化框架,适合用于处理更复杂的数据模型和关系。它不仅提供了对SQLite的封装,还支持内存存储、文件存储等多种持久化选项。

二、应用沙盒机制

每个iOS应用都有自己的应用沙盒,与其他应用隔离。这种机制保证了应用的数据安全。

1. 应用沙盒结构

沙盒目录主要包括以下几部分:

  1. 应用程序包:包含了所有的资源文件和可执行文件。
  2. Documents:用于存储需要持久化的数据,备份时会包含此目录。适合存储用户生成的文件(如游戏存档)。
  3. tmp:用于存储临时数据,可能会被系统清理,备份时不包含此目录。
  4. Library/Caches:用于存储体积大、不需要备份的非重要数据。系统可能会清理此目录。
  5. Library/Preferences:用于存储应用的所有偏好设置,备份时会包含此目录。

2. 获取应用沙盒目录

// 获取沙盒根路径
NSString *homeDirectory = NSHomeDirectory();

// 获取tmp目录
NSString *tmpPath = NSTemporaryDirectory();

// 获取Documents目录
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];

// 获取Library/Caches目录
NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];

// 获取Library/Preferences目录
NSString *preferencesPath = [NSSearchPathForDirectoriesInDomains(NSPreferencePanesDirectory, NSUserDomainMask, YES) firstObject];

三、属性列表(plist)存储

1. 存储数组或字典

// 存储数组到plist文件
NSArray *array = @[@"item1", @"item2", @"item3"];
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"data.plist"];
[array writeToFile:filePath atomically:YES];

// 读取数组
NSArray *arrayFromFile = [NSArray arrayWithContentsOfFile:filePath];

2. 存储字典到plist文件

NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:@"Jane" forKey:@"name"];
[dict setObject:@"123456" forKey:@"phone"];
[dict setObject:@27 forKey:@"age"];
[dict writeToFile:filePath atomically:YES];

// 读取字典
NSDictionary *dictFromFile = [NSDictionary dictionaryWithContentsOfFile:filePath];

四、偏好设置(NSUserDefaults)

1. 保存数据

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@"password" forKey:@"pwd"];
[defaults setBool:YES forKey:@"isOn"];
[defaults setInteger:10 forKey:@"num"];

2. 读取数据

NSString *pwd = [[NSUserDefaults standardUserDefaults] objectForKey:@"pwd"];
BOOL isOn = [[NSUserDefaults standardUserDefaults] boolForKey:@"isOn"];
NSInteger num = [[NSUserDefaults standardUserDefaults] integerForKey:@"num"];

五、NSData归档和解档

使用NSData可以将多个对象归档到同一个文件中,也可以实现深复制。

1. 归档多个对象

NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:person1 forKey:@"person1"];
[archiver encodeObject:person2 forKey:@"person2"];
[archiver finishEncoding];
[data writeToFile:filePath atomically:YES];

2. 解档多个对象

NSData *data = [NSData dataWithContentsOfFile:filePath];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
Person *person1 = [unarchiver decodeObjectForKey:@"person1"];
Person *person2 = [unarchiver decodeObjectForKey:@"person2"];
[unarchiver finishDecoding];

3. 实现自定义对象归档解档

Person.h

#import <Foundation/Foundation.h>

@interface Person : NSObject <NSCoding>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int age;
@end

Person.m

@implementation Person

- (void)encodeWithCoder:(NSCoder *)coder {
    [coder encodeObject:self.name forKey:@"name"];
    [coder encodeInt:self.age forKey:@"age"];
}

- (instancetype)initWithCoder:(NSCoder *)coder {
    if (self = [super init]) {
        self.name = [coder decodeObjectForKey:@"name"];
        self.age = [coder decodeIntForKey:@"age"];
    }
    return self;
}

@end

使用示例

Person *p = [[Person alloc] init];
p.name = @"John Doe";
p.age = 30;

// 归档
NSString *tempPath = NSTemporaryDirectory();
NSString *filePath = [tempPath stringByAppendingPathComponent:@"person.data"];
[NSKeyedArchiver archiveRootObject:p toFile:filePath];

// 解档
Person *decodedPerson = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
posted @   Mr.陳  阅读(1095)  评论(0编辑  收藏  举报
编辑推荐:
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
点击右上角即可分享
微信分享提示