zoukankan      html  css  js  c++  java
  • iOS6 编程:Core Data持久化数据存储(3)编写Core Data代码

    编写Core Data代码

    在前面创建Data Model的过程中,我们已经创建3个被管理对象(NSManagedObject),也就是实体对象。

    这里,我们创建其他Data Core框架中的对象,启用Core Data数据持久化存储功能。
    打开项目中的CartAppDelegate.h文件,添加NSManagedObjectContext属性和2个方法的原型定义。更新后的代码如下所示:

    #import <UIKit/UIKit.h>

    @interface CartAppDelegate : UIResponder
    @property (strong, nonatomic) UIWindow *window;

    @property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
    - (void) insertDataIntoShoppingCartDB;
    - (void) displayShoppingCart;

    @end

    打开 CartAppDelegate.m 文件,添加managedObjectContext属性的@synthesize编译指令。
    @synthesize managedObjectContext = _managedObjectContext;

    进一步实现managedObjectContext 实例变量的初始化方法。这段代码理稍微有点难理解。下面解释一下,首先获取存储文件(或数据库文件)存放位置,这里设置为App的Document目录下,存储文件(或数据库文件)为ShoppingCar Database。
    然后,创建NSPersistentStoreCoordinator 对象,指定存储类型(SQLite数据库)和存储路径。最后,实例化被管理对象上下文(Managed Object Context),并赋值其持久化存储协调器。
    - (NSManagedObjectContext *) managedObjectContext{
    if(_managedObjectContext == nil){
    NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory
    inDomains:NSUserDomainMask] lastObject];
    NSURL *storeDatabaseURL = [url URLByAppendingPathComponent:@"ShoppingCart.sqlite"];
    // 设置SQLite 数据库存储路径 /ShoppingCart.sqlite
    NSError *error = nil;

    //根据被管理对象模型创建NSPersistentStoreCoordinator 对象实例
    NSPersistentStoreCoordinator *persistentStoreCoordinator =
    [[NSPersistentStoreCoordinator alloc]
    initWithManagedObjectModel:[NSManagedObjectModel mergedModelFromBundles:nil]];

    //根据指定的存储类型和路径,创建一个新的持久化存储(Persistent Store)
    if(![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
    configuration:nil
    URL:storeDatabaseURL options:nil error:&error])
    {
    NSLog(@"Error while loading persistent store ...%@", error);
    }

    _managedObjectContext = [[NSManagedObjectContext alloc] init];

    //设置当前被管理对象上下文的持久化存储协调器
    [_managedObjectContext setPersistentStoreCoordinator:persistentStoreCoordinator];
    }

    // 返回初始化的被管理对象上下文实例
    return _managedObjectContext;
    }

    在CartAppDelegate.m文件实现接口中定义的insertDataIntoShoppingCartDB 方法,该方法主要是箱SQLite数据库中插入一些初始数据,供测试用途。
    下面的代码,实现向Customer、ShoppingCartMaster和ShoppingCartDetail三个实体中插入初始化数据。
    // 向SQLite插入一些初始数据
    - (void) insertDataIntoShoppingCartDB{
    // 创建Customer 被管理对象实例
    Customer *customer1 = (Customer *)[NSEntityDescription insertNewObjectForEntityForName:@"Customer"
    inManagedObjectContext:self.managedObjectContext];
    customer1.customerID = [NSNumber numberWithInt:1];
    customer1.customerName = @"客户姓名-笨笨";
    customer1.password = @"EntLib.com";
    customer1.userName = @"EntLib.com";

    // 创建ShoppingCartMaster 被管理对象实例
    ShoppingCartMaster *shoppingCartMaster1 = (ShoppingCartMaster *)[NSEntityDescription
    insertNewObjectForEntityForName:@"ShoppingCartMaster" inManagedObjectContext:self.managedObjectContext];
    shoppingCartMaster1.cartID = [NSNumber numberWithInt:100];
    shoppingCartMaster1.customerID = [NSNumber numberWithInt:1];

    // 创建ShoppingCartDetail 被管理对象实例
    ShoppingCartDetail *shoppingCartDetail1= (ShoppingCartDetail *)[NSEntityDescription
    insertNewObjectForEntityForName:@"ShoppingCartDetail" inManagedObjectContext:self.managedObjectContext];
    shoppingCartDetail1.cartID = [NSNumber numberWithInt:100];
    shoppingCartDetail1.currentPrice = [NSDecimalNumber decimalNumberWithDecimal:
    [[NSNumber numberWithFloat:18.5f] decimalValue]];

    shoppingCartDetail1.productID = @"1-111-111";
    shoppingCartDetail1.productName= @"Hello Kitty - iPhone 5 手机";
    shoppingCartDetail1.productSysNo = [NSNumber numberWithInt:10];

    ShoppingCartDetail *shoppingCartDetail2= (ShoppingCartDetail *)[NSEntityDescription
    insertNewObjectForEntityForName:@"ShoppingCartDetail" inManagedObjectContext:self.managedObjectContext];
    shoppingCartDetail2.cartID = [NSNumber numberWithInt:100];
    shoppingCartDetail2.currentPrice = [NSDecimalNumber decimalNumberWithDecimal:
    [[NSNumber numberWithFloat:18.5f] decimalValue]];

    shoppingCartDetail2.productID = @"2-222-111";
    shoppingCartDetail2.productName= @"Hello Kitty - iPad 3 平板电脑";
    shoppingCartDetail2.productSysNo = [NSNumber numberWithInt:10];

    // 赋值关系属性实例变量
    // 开发测试的时候,可以把下面的代码注释掉,分析比较一下
    customer1.cart = shoppingCartMaster1;
    [shoppingCartMaster1 addDetailObject:shoppingCartDetail1];
    [shoppingCartMaster1 addDetailObject:shoppingCartDetail2];

    // 保存数据,持久化存储 SQLite数据库
    // 开发测试的时候,可以把下面的代码注释掉,分析比较一下
    /*if([self.managedObjectContext hasChanges]){
    [self.managedObjectContext save:nil];
    }*/

    }

    注意,上面的代码中,我们把向SQLite数据库写入数据的save操作注释了。这个只是在测试过程中,避免反复向数据库中插入初始数据。如果将上述代码注释去掉,就可以实现向SQLite数据库中存储数据。

    继续在CartAppDelegate.m文件中实现接口中定义的displayShoppingCart方法。该方法用来在Xcode的调试窗口输出被管理对象上下文中的实体数据。
    // 显示SQLite 数据库,购物车中的内容
    - (void) displayShoppingCart{
    // NSFetchRequest 对象用来检索数据
    NSFetchRequest *request = [[NSFetchRequest alloc] init];

    // 根据指定Entity名称和被管理对象上下文,创建NSEntityDescription对象,
    NSEntityDescription *myEntityQuery = [NSEntityDescription
    entityForName:@"Customer"
    inManagedObjectContext:self.managedObjectContext];
    // 指定实体
    [request setEntity:myEntityQuery];

    NSError *error = nil;
    // 返回符合查询条件NSFetchRequest的记录数组
    NSArray * customerArr = [self.managedObjectContext executeFetchRequest:request error:&error];
    NSInteger recordCount = [customerArr count];
    NSLog(@"Record Count: %d", recordCount);
    for (int i=0; i< recordCount; i++){
    // 数组中元素为Customer 被管理对象
    Customer *customer = (Customer *)[customerArr objectAtIndex:i];
    NSLog(@"CustomerName: %@",  customer.customerName);

    // 获取Customer 对应关系的ShoppingCartMaster 对象,一对一关系
    ShoppingCartMaster *cart = customer.cart;
    NSLog(@"我的购物车: %@", cart.cartID);

    // 获取ShoppingCartMaster对象中所有的detail 对象数组,一对多关系
    NSArray *productList = [cart.detail allObjects];
    int numberOfProducts = [productList count];
    NSLog(@"购物车商品数:%d", numberOfProducts);

    // 遍历ShoppingCartDetail 数组
    for(int i=0; i< numberOfProducts; i++){
    ShoppingCartDetail *detail = [productList objectAtIndex:i];
    NSLog(@"购物车商品:%@", detail.productName);
    }
    }
    }

    注意,这里我们使用被管理对象上下文(Managed Object Context)中获取数据的,也就是在内存中获取数据,因此前面insertDataIntoShoppingCartDB方法中的[self.managedObjectContext save:nil] 代码行,即使注释,也可以获得返回结果。

    最后,我们还需要修改CartAppDelegate.m文件中的application:didFinishLaunchingWithOptions:方法中的代码。更新后的代码如下,主要是添加对我们前面定义的2个方法的调用。
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    // Override point for customization after application launch.
    [self insertDataIntoShoppingCartDB];
    [self displayShoppingCart];

    return YES;
    }

    至于application:didFinishLaunchingWithOptions: 方法在什么时候调用的?
    这里,我们需要简单介绍一下iOS应用程序的生命周期。

    iOS应用程序的生命周期

    在我们创建应用程序时,在项目的Supporting Files 文件夹中,自动创建了main.m文件。

    main.m 是程序的入口,我们看一下main.m文件的代码。

    #import <UIKit/UIKit.h>
    #import "CartAppDelegate.h"

    int main(int argc, char *argv[])
    {
    @autoreleasepool {
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([CartAppDelegate class]));
    }
    }

    在main中执行一个方法UIApplicationMain,该方法返回一个UIApplicationMain对象表示我们的这个应用程序对象。
    第四个参数是一个字符串,就是应用程序委托类CartAppDelegate,这个也是在创建项目过程中,Xcode自动创建的。
    前面我们修改的application:didFinishLaunchingWithOptions: 方法就在这个类中,iOS程序启动时总会调用此方法。

    ——

    未完待续!!!

  • 相关阅读:
    图书管理系统---基于form组件和modelform改造添加和编辑
    Keepalived和Heartbeat
    SCAN IP 解释
    Configure Active DataGuard and DG BROKER
    Oracle 11gR2
    我在管理工作中積累的九種最重要的領導力 (李開復)
    公募基金公司超融合基础架构与同城灾备建设实践
    Oracle 11g RAC for LINUX rhel 6.X silent install(静默安装)
    11gR2 静默安装RAC 集群和数据库软件
    Setting Up Oracle GoldenGate 12
  • 原文地址:https://www.cnblogs.com/tuncaysanli/p/2727905.html
Copyright © 2011-2022 走看看