数据存储

来源:互联网 发布:淘宝农村市场调研报告 编辑:程序博客网 时间:2024/05/21 19:18

数据存储分为运行时存储和持久性存储。实现持久性存储有5种方式:

  1. plist属性列表
  2. 偏好设置
  3. 归档
  4. SQLite
  5. CoreData

关于数据存储,我们首先需要了解沙盒机制:这里有介绍--- 沙盒机制

plist属性列表

在页面输入框信息填写完毕后,读取输入框中的数据,封装到对象中,最后将对象转为属性列表持久保存在plist文件中:

- (IBAction)save:(UIButton *)sender {    //获取页面数据    NSString *name = self.nameField.text;    NSString *birthday = self.birthdayField.text;    NSString *number = self.numberField.text;    NSInteger sex = self.sexSegment.selectedSegmentIndex;    //判断表格是否填写完整    if(!name.length || !birthday.length || !number.length) {        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"信息不完整,请重新填写" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil];        [alert show];    return;    }    [self.view endEditing:YES];    //创建字典对象封装学生信息    NSMutableDictionary *Student = [[NSMutableDictionary alloc] init];    NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];    [Student setObject:name forKey@"Name"];    [Student setObject:birthday forKey@"Birthday"];     [Student setObject:number forKey@"Number"];    [Student setObject:[NSNumber numberWithInteger:sex] forKey@"Sex"];    [dic setObject:Student fotKey:@"Student"];    //字典对象转为属性列表持久保存在plist文件中    if ([dic writeToFile:[self filePath] atomically:YES]){        UIAlertView *alert = [[UIAlertView allic] initWithTitle:@"提示" message:@"保存成功" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil];        [alert show];    }    return;}//获取plist文件目录- (NSString *)filePath {    //获取沙盒目录    NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);    NSString *path = array[0];    return [path stringByAppendingPathCompenent:@"Student.plist"];}

完成后,可在沙盒目录的Document文件目录下看到新建的Stundent.plist文件。

读取plist文件中的数据:

- (void)read{   //从文件初始化字典对象   NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:[self filePath]];   NSdictionary *Lily = [dict objectForKey@"Student"];   //将plist文件的信息显示到对应的文本框和分段控件中   if (Lily){       self.nameField.text = [Lily objectForKey:@"Name"];       self.birthdayField.text = [Lily objectForKey:@"Birthday"];       self.numberField.text = [Lily objectForKey:@"Number"];       self.sexSegment.selectedSegmentIndex = [[Lily objectForKey:@"Sex" intValue];   }}

ATTENTION:
属性文件虽然可以很方便地保持和加载数据,但是它只支持可被序列化的数据类型,如NSArray和NSDictionary。自定义对象也不能存储。
只有NSDictionary-NSArray-NSString-NSNumber-NSData-NSDate及其可修改类对象或者嵌套对象,才能以属性列表的形式保存。

偏好设置

iOS提供了一种偏好设置,它的本质是plist文件,专门用来保存应用程序配置信息,如保存用户名/密码等的设置是否打开等,默认情况下,使用系统偏好设置存储的数据,该文件位于Library下的Preferences文件夹下。

  • 存取偏好设置,需要通过NSUserDefaults类的实例来实现,每个应用有一个单例的该实例,获取方法:
NSUserDefaults *userDefaults = [NSDefaults standardUserDefaults];
  • 使用偏好设置保存数据的方法,根据数据类型不同有:
- (void)setObject:(id)value forKey:(NSString *)defaultName;- (void)setInteger:(NSInteger)value forKey:(NSString *)defaultName;- (void)setFloat:(float)value forKey:(NSString *)defaultName;- (void)setDouble:(double)value forKey:(NSString *)defaultName;- (void)setBool:(BOOL)value forKey:(NSString *)defaultName;

与plist属性列表相比,使用偏好设置存储数据时,不需要传入路径参数,因此相对而言比较简便。

  • 读取偏好设置中存储的数据时,依据数据类型不同,NSDefaults类也提供不同的方法:
- (id)objectForKey:(NSString *)defaultName;- (NSString *)stringForKey:(NSString *)defaultName;- (NSArray *)arrayForKey:(NSString *)defaultName;- (NSDictionary *)dictionaryForKey:(NSString *)defaultName;- (NSData *)dataForKey:(NSString *)defaultName;- (NSArray *)stringArrayForKey:(NSString *)defaultName;- (NSInteger)integerForKey:(NSString *)defaultName;- (float)floatForKey:(NSString *)defaultName;- (double)doubleForKey:(NSString *)defaultName;- (BOOl)boolForKey:(NSString *)defaultName;

注意
userDefaults设置数据时,不是立刻写入到指定文件,而是根据时间戳定时地把缓存中的数据写入本地磁盘,所以当调用setObject:forKey 的方法后,数据有可能还没有写如磁盘,应用程序就终止了。针对这个问题,可以通过调用synchronize方法强制写入,实现同步,该方法定义如下:

- (BOOL)synchronize;

另外,偏好设置专门用来保存应用程序的配置信息的,它会将所有的数据保存到同一个文件中,若数据过多,则不便于管理。因此,一般情况下,偏好设置适用于保存少量数据。

对象归档

在iOS开发中,经常需要保持一些对象,属性列表和偏好设置均不能实现。针对这种情况,iOS提供了对象归档技术,它可以采用序列化的方式,实现对象的储存。

所谓对象归档,就是将一个或多个对象,采用序列化的方式保存到指定的文件,再以反序列化的方法从文件恢复成对象,这个过程类似于压缩和解压缩的过程。通常,对象归档的操作主要有两方面:

  • 对象归档:以一种不可读的方式,将对象写入到指定的文件中
  • 对象反归档:从指定文件中读取数据,并自动重建对象。
    针对则两种情况,iOS有相应的类:

1, NSKeyedArchiver类
NSKeyedArchiver类直接继承NSCoder类,可以将对象归档到指定文件,为此该类提供两个类方法:

+ (NSData *)archivedDataWithRootObject:(id)rootObject;+ (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path;

2, NSKeyedUnarchiver类
NSKeyedUnarchiver类直接继承NSCoder类,负责从文件中恢复对象,为此也有两个方法:

+ (id)unarchiveObjectWithData:(NSData *)data;+ (id)unarchiveObjectWithFile:(NSString *)path;

NSCoding协议

对象归档技术中有一个非常重要的协议NSCoding,方式遵守了NSCoding协议的自定义对象,都可以实现对象的归档和反归档。该协议中定义了两个方法,这两个方法时对象归档必须要实现的:

@protocol NSCoding//该方法负责归档对象的所有实例变量- (void)encodeWithCoder:(NSCoder *)aCoder;//该方法负责恢复该对象的实例变量的值- (id)initWithCoder:(NSCoder *)aDecoder;

我们可以通过重写这两个方法,来指定如何归档和恢复对象的每一个实例变量,为此NSCoder类提供了相应的方法来实现对象的归档,恢复对象实例变量的方法:

  • 归档数据的方法:
//将Object类型编码,使其与字符串类型的键相关联- (void)encodeObject:(id)obj forKey:(NSString *)key;- //将BOOL类型编码,使其与字符串类型的键相关联- (void)encodeBool:(BOOL)boolv forKey:(NSString *)key;- //将int类型编码,使其与字符串类型的键相关联- (void)encodeInt:(int)intv forKey:(NSString *)key;- //将float类型编码,使其与字符串类型的键相关联- (void)encodeFloat:(float)realv forKey:(NSString *)key;- //将double类型编码,使其与字符串类型的键相关联- (void)encodeDouble:(double)realv forKey:(NSString *)key;- //将NSInteger类型编码,使其与字符串类型的键相关联- (void)encodeInteger:(NSInteger)intv forKey:(NSString *)key;
  • 恢复对象实例变量的方法:
//解码并返回一个与给定键相关联的Object类型的值- (id)decodeObjectForKey:(NSString *)key;//解码并返回一个与给定键相关联的BOOL类型的值- (BOOL)decodeBoolForKey:(NSString *)key;//解码并返回一个与给定键相关联的int类型的值- (int)decodeIntForKey:(NSString *)key;//解码并返回一个与给定键相关联的float类型的值- (float)decodeFloatForKey:(NSString *)key;//解码并返回一个与给定键相关联的double类型的值- (double)decodeDoubleForKey:(NSString *)key;//解码并返回一个与给定键相关联的NSInteger类型的值- (NSInteger)decodeIntegerForKey:(NSString *)key;

注意
1,NSString,NSDictionary,NSNumber,NSArray等类型的对象可以直接归档和反归档,它们默认已经实现NSCoding协议
2,只要在类中实现的每个属性都是基本数据类型,如int或float,或者都是负荷NSCoding协议的某个类的实例,你就可以对你的对象进行完整归档。

归档成功后,保存的文件扩展名时任意的,没有任何限制。

SQLite数据库

待定

Core Data

待定

0 0