ios学习笔记之四种数据持久化方法


ios下主要有四种数据持久化方法:

1.属性列表

2.对象归档

3.SQLite3

4.CoreData

下面分别简单介绍这四种方法。

1.属性列表

将支持序列化的object C对象add至NSArray或NSDictionary中,然后调用这两个对象的writeToFile方法,例如:

[MyArray writeToFile:@"/filepath/file.plist" atomically=YES]

在object C中,支持序列化的对象有:

NSArray

NSMutableArray

NSDictionary

NSMutableDictionary

NSData

NSMutableData

NSString

NSMutableString

NSNumber

NSDate

因此,属性列表方法有个缺点,就是不能将自定义的对象持久化.因为自定义对象不支持序列化.

 

2.对象归档

要使用对象归档,对象必须实现NSCoding协议.大部分Object C对象都符合NSCoding协议,也可以在自定义对象中实现NSCoding协议,要实现NSCoding协议,只许实现两个方法:

- (void) encodeWithCoder:(NSCoder *)encoder 与 -(void)initWithCoder:(NSCoder *)encoder

同时,建议对象也同时实现NSCopying协议,该协议允许复制对象,要实现NSCopying协议须实现 -(id)copyWithZone:(NSZone *)zone 方法 。

对对象归档的主要步骤如下:

NSMutableData *data = [[NSMutableData alloc] init];    //建一个NSMutableData对象,用于包含编码数据。

NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];

[archiver encodeObject:myObject forKey:myKey];   //使用键/值编码将对象归档至data中

[archiver finishEncoding];

BOOL success = [data writeToFile:@"filepath/myfile.plist" atomically:YES];   //将NSMutableData写入文件系统

[unarchiver release];

[data release];

[myObject release];

 

对对象解档的主要步骤如下:

NSData *data = [[NSMutableData alloc]initWithContentsOfFile: @"filepath/myfile.plist" ]; 

NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];

MyObject *myObject = [unarchiver decodeObjectForKey:myKey];

[unarchiver finishDecoding];

[unarchiver release];

[data release];

[myObject release];

[archiver release];

[data release];

 

3. SQLite3

SQLite3是Iphone的嵌入式SQL数据库。如果应用程序需要所有对象中符合某些条件的某个对象,SQLite可执行该操作,而避免将所有对象都加载到内存,减小开销。

在ios中,打开和关闭数据库的方法如下:

sqlite3 *database;

int result = sqlite3_open(pathString, &database);

sqlite3_close(database);

sqlite3是采用可移植的C(而非Objective C)写的,因此pathString必须为string类而不能为NSString,必须将NSString转为string:

char *stringPath = [pathString UTF8String];

 

以下是几个数据库操作的例子,包括create table, select from table和 insert into table

    NSString *createSQL = @"CREATE TABLE IF NOT EXISTS FIELDS (ROW INTEGER PRIMARY KEY, FIELD_DATA TEXT);";
    if (sqlite3_exec (database, [createSQL  UTF8String],
                      NULL, NULL, &errorMsg) != SQLITE_OK) {
        sqlite3_close(database);
    }
    
    NSString *query = @"SELECT ROW, FIELD_DATA FROM FIELDS ORDER BY ROW";
    sqlite3_stmt *statement;
    if (sqlite3_prepare_v2( database, [query UTF8String],
                           -1, &statement, nil) == SQLITE_OK) {
        while (sqlite3_step(statement) == SQLITE_ROW) {
            int row = sqlite3_column_int(statement, 0);                               //index 0 代表ROW域
            char *rowData = (char *)sqlite3_column_text(statement, 1);
            
            NSString *fieldName = [[NSString alloc]
                                   initWithFormat:@"field%d", row];
            NSString *fieldValue = [[NSString alloc]
                                    initWithUTF8String:rowData];
        }
        sqlite3_finalize(statement);
    }


        char *update = "INSERT OR REPLACE INTO FIELDS (ROW, FIELD_DATA) VALUES (?, ?);";
        sqlite3_stmt *stmt;
        if (sqlite3_prepare_v2(database, update, -1, &stmt, nil) == SQLITE_OK) {
            sqlite3_bind_int(stmt, 1, rowNum);                                                           //将rowNum绑定之第一个问号
            sqlite3_bind_text(stmt, 2, [field.text UTF8String], -1, NULL);
        }
        if (sqlite3_step(stmt) != SQLITE_DONE)
            NSAssert1(0, @"Error updating table: %s", errorMsg);
        sqlite3_finalize(stmt);

 

 

4. Core Data

尽管Core Data也是使用SQLite保存数据,但是使用它不需要编写任何SQL语句,程序员只需操作各个对象,剩下的工作交给Core Data,这个有点类似于JPA。

要使用Core Data,需要在Xcode中的数据模型编辑器中设计好各个实体以及定义好他们的属性和关系。之后,通过操作这些对象,结合Core Data完成数据的持久化:

  NSManagedObjectContext *context = [appDelegate managedObjectContext];
  NSError *error;

  NSString *fieldName = [NSString stringWithFormat:@"line%d", i];
  UITextField *theField = [self valueForKey:fieldName];
        
   NSFetchRequest *request = [[NSFetchRequest alloc] init];
        
   NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Line"
                                                             inManagedObjectContext:context];                                     //创建描述语句,需求Line对象。类似于在数据库中限定为Line表。
   [request setEntity:entityDescription];
   NSPredicate *pred = [NSPredicate predicateWithFormat:@"(lineNum = %d)", i];   //创建限制性语句,类似于SQL语句中的 where lineNum = i
   [request setPredicate:pred];
        
   NSManagedObject *theLine = nil;
       
   NSArray *objects = [context executeFetchRequest:request error:&error];
        
   if (objects == nil){
       NSLog(@"There was an error!");
       // Do whatever error handling is appropriate
   }
   if ([objects count] > 0)    //如果符合条件的object存在,则取出
        theLine = [objects objectAtIndex:0];
    else   //如果不存在,则插入一个新的.
         theLine = [NSEntityDescription insertNewObjectForEntityForName:@"Line"
                                                    inManagedObjectContext:context];
        
        [theLine setValue:[NSNumber numberWithInt:i] forKey:@"lineNum"];  //设置这个object的属性,coredata会自动将其写入sqlite
        [theLine setValue:theField.text forKey:@"lineText"];
        
        [request release];

   }
   [context save:&error];

下面是其取数据的过程。

 

    Core_Data_PersistenceAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *context = [appDelegate managedObjectContext];
    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Line"
                                                         inManagedObjectContext:context];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entityDescription];
    
    NSError *error;
    NSArray *objects = [context executeFetchRequest:request error:&error];
    if (objects == nil)
    {
        NSLog(@"There was an error!");
        // Do whatever error handling is appropriate
    }
    
    for (NSManagedObject *oneObject in objects)   //每一个对象在CoreData中都表示为一个NSManagedObject对象(类似于数据库表中的每一行),他的属性通过键/值 方式获取
    {
        NSNumber *lineNum = [oneObject valueForKey:@"lineNum"];
        NSString *lineText = [oneObject valueForKey:@"lineText"];
    }
    [request release];

更多 0

    • 0
      点赞
    • 0
      收藏
      觉得还不错? 一键收藏
    • 0
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值