iOS 数据持久化之CoreData(二)堆栈建立和基本操作Demo

原创Blog,转载请注明出处
blog.csdn.net/hello_hwc
欢迎关注我的iOS SDK详解专栏
http://blog.csdn.net/column/details/huangwenchen-ios-sdk.html


前言:本文会通过一个完整的工程创建,讲解

  • CoreData的堆栈创建
  • 四种基本的操作(查询,创建,删除,更新)
  • 简单的MVC设计
  • 如何使用Block传递Action,缩减代码量
  • 再CoreData使用类别扩展NSManagedObject方法

Demo下载
http://download.csdn.net/detail/hello_hwc/8692083

注意,这个Demo侧重讲解如何建立CoreData堆栈,以及常见的四种操作,为后续文章的讲解做铺垫的,所以非常简单,简单到体现不到CoreData的优点,如果你哪怕写过一个使用了CoreData的工程,那就这篇就可以直接不看了。


Demo效果

四种基本操作
技术分享
点击Query All
Log输出

2015-05-13 10:26:13.534 QuiteSimpeCoreDataDemo[3029:62136] (
    "name:Lucy age:21",
    "name:Tom age:20",
    "name:jack age:21"
)

然后,添加一个新的Person,点击Create
技术分享
输出

2015-05-13 10:27:03.764 QuiteSimpeCoreDataDemo[3029:62136] Create Successfully.Id is 0xd000000000100000 <x-coredata://ACB1C333-E7B3-4D6A-BF58-7061952D95AD/Person/p4>

然后更新
技术分享


输出

2015-05-13 10:28:21.109 QuiteSimpeCoreDataDemo[3029:62136] Update Successfully

在查询全部,看到年龄更新成功

2015-05-13 10:30:06.557 QuiteSimpeCoreDataDemo[3029:62136] (
    "name:Lily age:24",
    "name:Lucy age:21",
    "name:Tom age:20",
    "name:jack age:21"
)

删除
技术分享
输出

2015-05-13 10:31:27.312 QuiteSimpeCoreDataDemo[3029:62136] Delete successfully

再查询,发现删除成功

2015-05-13 10:31:42.711 QuiteSimpeCoreDataDemo[3029:62136] (
    "name:Lucy age:21",
    "name:Tom age:20",
    "name:jack age:21"
)

Demo的建立过程

  • 新建一个工程,注意选中使用CoreData

技术分享

  • 查看AppDelegate.m,会发现很多和CoreData创建堆栈相关的代码,为了代码的解耦合,把这些代码以AppDelegate.m中的代码拷贝到一个新建类(Store)中,这个类点作用就是创建堆栈,提供NSManagedContext
    Store.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface Store : NSObject

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;

- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;

@end

再看看Store.m各个部分的内容

//获取DocumentDirectory
- (NSURL *)applicationDocumentsDirectory {
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

获取对象图模型,这里的对象图名字就是这个文件的名字
技术分享

- (NSManagedObjectModel *)managedObjectModel {
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"QuiteSimpeCoreDataDemo" withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return _managedObjectModel;
}

创建持久化存储协调器

 - (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }    
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"QuiteSimpeCoreDataDemo.sqlite"];
    NSError *error = nil;
    NSString *failureReason = @"There was an error creating or loading the application‘s saved data.";
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application‘s saved data";
        dict[NSLocalizedFailureReasonErrorKey] = failureReason;
        dict[NSUnderlyingErrorKey] = error;
        error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();//这里为了方便调试,正常的App不要这样写
    }

    return _persistentStoreCoordinator;
}

创建Managed Context

- (NSManagedObjectContext *)managedObjectContext {
    // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (!coordinator) {
        return nil;
    }
    _managedObjectContext = [[NSManagedObjectContext alloc] init];
    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    return _managedObjectContext;
}

保存到磁盘

 - (void)saveContext {
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil) {
        NSError *error = nil;
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {

            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }
}

  • 点击QuiteSimpleCoreDataDemo.xcdatamodeld,创建一个Entity,命名为Person,添加两个属性,name和age,如图
    技术分享

  • Editor- CreateNSManaged Subclass - 一致勾选-创建声称两个文件,Person.h,Person.m

    技术分享


创建Person的类别Function+Person,在这里为NSManagedObject添加方法,不要在类中直接添加,因为下次在自动生成时候会把这之前的覆盖掉。
Function+Person.h文件

#import "Person.h"

@interface Person (Functions)
+(NSString *)entityName;
+(Person *)insertNewObjectInManagedObjectContext:(NSManagedObjectContext *) context;
@end

Function+Person.m文件

#import "Person+Functions.h"

@implementation Person (Functions)
+(NSString *)entityName{
    return @"Person";
}
+(Person *)insertNewObjectInManagedObjectContext:(NSManagedObjectContext *) context{
    return [NSEntityDescription insertNewObjectForEntityForName:[self entityName] inManagedObjectContext:context];
}
//重写Description,方便Log
-(NSString *)description{
    return [NSString stringWithFormat:@"name:%@ age:%ld",self.name,(long)self.age.integerValue];
}
@end

然后,回到viewController进行相关的处理
使用AlertController作为输入,创建一个公共方法,这里的CoreDataAction是我定义的一个Block,传入如何处理数据的动作。

typedef void(^CoreDataAction)(NSString * name,NSString * age);
-(void)AlertTextFieldWithTitle:(NSString *)actionTitle Action:(CoreDataAction) actionBlock {
    UIAlertController * alert = [UIAlertController alertControllerWithTitle:actionTitle message:nil preferredStyle:UIAlertControllerStyleAlert];
    [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
       textField.placeholder = @"Name";
    }];
    [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
        textField.placeholder = @"age";
    }];
    [alert addAction:[UIAlertAction actionWithTitle:actionTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        NSArray * textfields = alert.textFields;
        UITextField * nameTextfields = textfields[0];
        UITextField * ageTextFields = textfields[1];
        actionBlock(nameTextfields.text,ageTextFields.text);
    }]];
    [alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
    [self presentViewController:alert animated:YES completion:nil];
}

查询当前Name的Person是否存在(本工程Person的name不允许重复),存在则返回,不存在则返回nil

-(Person *)personExistWithName:(NSString *)name{
    NSFetchRequest * fetchRequest = [NSFetchRequest fetchRequestWithEntityName:[Person entityName]];
    //This is an array
    fetchRequest.predicate = [NSPredicate predicateWithFormat:@"name =  %@",name];
    NSError *error = nil;
    NSArray *fetchedObjects = [self.store.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    if (fetchedObjects == nil) {
        return nil;
    }else{
        return [fetchedObjects lastObject];
    }
}

对应的四个Button的target-action
查询

- (IBAction)queryAll:(id)sender {
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:[Person entityName] inManagedObjectContext:self.store.managedObjectContext];
    [fetchRequest setEntity:entity];
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name"
                                                                   ascending:YES];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]];

    NSError *error = nil;
    NSArray *fetchedObjects = [self.store.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    if (fetchedObjects == nil) {
        NSLog(@"It is empty");
    }else{
        NSLog(@"%@",fetchedObjects.description);
    }
}

更新

- (IBAction)update:(id)sender {
    [self AlertTextFieldWithTitle:@"Update" Action:^(NSString *name, NSString *age) {
        Person * person = [self personExistWithName:name];
        if (person != nil) {
            person.age = @(age.integerValue);
            [self.store saveContext];
            NSLog(@"Update Successfully");
        }else{
            NSLog(@"Person does not exist,can not update");
        }
    }];
}

创建

- (IBAction)Create:(id)sender {
    [self AlertTextFieldWithTitle:@"Create" Action:^(NSString *name, NSString *age) {
        if ([self personExistWithName:name] == nil) {
            Person * person = [Person insertNewObjectInManagedObjectContext:self.store.managedObjectContext];
            person.name = name;
            person.age =  @(age.integerValue);
            [self.store saveContext];
            NSLog(@"Create Successfully.Id is %@",person.objectID.description);

        }else{
            NSLog(@"This peson  exist before,can not create");
        }
    }];
}

删除

- (IBAction)Delete:(id)sender {
    [self AlertTextFieldWithTitle:@"Delete" Action:^(NSString *name, NSString *age) {
        Person * person = [self personExistWithName:name];
        if (person != nil) {
            [self.store.managedObjectContext deleteObject:person];
            NSLog(@"Delete successfully");
        }else{
            NSLog(@"This does not exist before,can not delete");
        }
    }];
}

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。