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程序启动时总会调用此方法。

    ——

    未完待续!!!

  • 相关阅读:
    C#几种截取字符串的方法小结
    KinSlideshow参数设置说明
    WinForm程序中两份mdf文件问题的解决
    全国省市数据库
    ASP.NET项目中使用CKEditor +CKFinder 实现上传图片
    mht文件无法打开的解决办法
    Non-parametric tests
    Plot transpant lines in Matleb 在Matlab中绘制透明线条
    Which HRV method to use: FFT or Autoregressive?
    SPM How-tos SPM预处理及统计分析指南
  • 原文地址:https://www.cnblogs.com/tuncaysanli/p/2727905.html
Copyright © 2011-2022 走看看