使用Core Data

来源:互联网 发布:linux usleep 返回值 编辑:程序博客网 时间:2024/06/02 08:07


1.实体和托管对象

在Core Data之前,创建数据模型的方式是创建一个NSObject的子类,并且让它们遵循NSCoding和NSCopying,以便能够对它们进行归档,Core Data使用完全不一样的方法。不再需要创建类,而是在数据模型编辑器中创建一些实体(Entity),然后在代码中为这些实体创建托管对象。


实体由属性组成:

特性(attribute):与实例变量在类中的作用相同,用于保存数据

-------------

关系(relationship):定义实体之间的关系。

举例:实体Person,包含了hairColor,eyeColor,height等特性。实体HomeAddress,包含address,tel等特性。我们希望在Person和HomeAddress之间创建一个关系,关系可以一对一或者一对多。从Person到HomeAddress的关系可以是一对一,因为大多数人都只有一个家庭地址。从HomeAddress到Person可以是一对多,因为多个Person住在同一个HomeAddress。

-------------

提取属性(fetched propety):关系的备选方法。

使用提取属性可以创建一个可在提取时被评估的查询,从而确定哪些对象属于这个关系。

举例:Person对象可以拥有一个Neighbors的提取属性,该属性查找数据存储中与这个Person的HomeAddress拥有相同邮政编码的所有HomeAddress对象。

-------------


2.K-V编码

Core Data 使用键值编码来设置属性或检索它们的已有值。

在操作托管对象时,用于设置和检索属性值的键 就是特性的名称。

获取特性name中的值方法:  NSString  *name = [myManagedObject valueForKey:@"name"];

为特性name设置新值:[myManagedObject setValue:@"Gregor Overlander" forKey @"name"];


3.在上下文中结合它们

托管对象的活动区域位于所谓的持久存储中。默认情况下,Core Data应用程序将持久存储实现为存储在应用程序Documents目录中的SQLite数据库

我们不直接操作持久存储,而是使用托管对象上下文(NSManagedObjectContext)。托管对象上下文协调对持久存储的访问,同时保存自上次保存对象以来修改过的属性的信息。还可以通过撤销管理器来注册所有更改,这就意味着我们可以撤销单个操作或者回滚到上次保存的数据。

NSManagedObjectModel 负责在运行时加载和标识使用Xcode中的数据模型编辑器创建的数据模型


4.创建新的托管对象

先了解类NSEntityDescription,它的作用是,跟踪在应用程序的数据模型中定义的所有实体。(除了在应用程序的数据模型中有定义实体,还有地方定义实体吗?这是不是很啰嗦?)

使用NSEntityDescription类中的insertNewObjectForEntityForName:inManagedOjectContext:方法,创建一个实例,表示内存中的单个实体。它返回的是一个NSManagedObject实例,或者是NSManagedObject的子类。

theLine = [NSEntityDescription insertNewObjectForEntityForName:@"EntityName" inManagedObjectContext:context];

调用结束后,对象存在于上下文中,但还不是持久存储的一部分。下一次托管对象上下文的save:方法被调用时,这个对象才被添加到持久存储内。


5.检索托管对象

从持久存储中获取托管对象,使用获取请求。


首先创建获取请求,并为它提供实体描述,指定了希望检索的一个或多个对象实体。

NSFetchRequest *request = [[NSFetchRequest alloc] init];

NSEntityDescription *entityDescr = [NSEntityDescription entityForName @"EntityNane", inManagedObjectContext:context];

[request setEntity:entityDescr];

使用NSPredicate类为获取请求指定条件。

NSPredicate *pred = [NSPredicate predicateWithFormate:@"(name = %@)", nameString];

[request setPredicate: pred];

使用NSManagedObjectContext中的实例方法执行获取请求:

NSError *error;

NSArray *objects = [context executeFetchRequest:request error:&error];

if (objects == nil)

{

//错误处理

}

context将跟踪对objects中返回的托管对象的所有更改,context发送save:信息可保存更改



------------------------------------------------------------------

在实际使用过程中的实现

在应用程序中,如何创建托管对象上下文:

    BIDAppDelegate *delegate = [UIApplication sharedApplication].delegate;    NSManagedObjectContext *contex = [delegate managedObjectContext];

直接通过实例名创建获取请求

    NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:kLineEntityName];

检索所有对象

    NSError *error;    NSArray *objects = [contex executeFetchRequest:request error:&error];    if (objects == nil) {        NSLog(@"There was an error!");    }

历遍已获取对象的数组

    for (NSManagedObject *oneObject in objects){        int lineNum = [[oneObject valueForKey:kLineNumberKey] intValue];        NSString *lineText = [oneObject valueForKey:kLineTextKey];        UITextField *textField = self.lineFields[lineNum];        textField.text = lineText;    }

在应用程序转到后台或者退出时通知

    UIApplication *app = [UIApplication sharedApplication];    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:app];

- (void)applicationWillResignActive:(NSNotification *)notification{    BIDAppDelegate *delegate = [UIApplication sharedApplication].delegate;    NSManagedObjectContext *context = [delegate managedObjectContext];    NSError *error;        for (int i = 0; i < 4; i ++) {        UITextField *textField = self.lineFields[i];        NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:kLineEntityName];        NSPredicate *pred = [NSPredicate predicateWithFormat:@"(%K = %d)", kLineNumberKey, i];        [request setPredicate:pred];                NSArray *objects = [context executeFetchRequest:request error:&error];        if (objects == nil) {            NSLog(@"There was an error!");        }                NSManagedObject *theLine = nil;        if ([objects count] > 0) {            theLine = [objects objectAtIndex:0];        } else {            theLine = [NSEntityDescription insertNewObjectForEntityForName:kLineEntityName inManagedObjectContext:context];        }                [theLine setValue:[NSNumber numberWithInt:i] forKey:kLineNumberKey];        [theLine setValue:textField.text forKey:kLineTextKey];    }    [delegate saveContext];}




0 0