美文网首页iOS开发
CoreData的使用以及结果的抓取

CoreData的使用以及结果的抓取

作者: hunterzhu | 来源:发表于2016-08-19 21:28 被阅读551次

    今天聊聊CoreData的使用,通过懒加载的方式来创建,和数据库中数据的抓取,fetchedResultController的代理,一些简单的使用。
    coredata用于做数据持久化,适合大数据量的存储和查询
    coredata虽然不是数据库,但是可以使用数据库,xml等方式来存储数据,看看coredata的用法吧!

    1.创建一个coredatamodel

    datamodel.png

    2.创建一个实体


    addentity.png

    3.添加属性


    添加属性.png

    4.创建model

    ![Uploading addmodel_790071.png . . .]
    model.png

    好了这些实体,model也创建完了,开始来操作这些东西了。

    第一步:
    创建一个管理类:用到了懒加载的方式。创建了一个sqlite的数据库。
    .h

    //
    //  CoreDataManager.h
    //  CoreData-demo
    //
    //  Created by mac on 16/8/19.
    //  Copyright © 2016年 mac. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    #import <CoreData/CoreData.h>
    @interface CoreDataManager : NSObject
    //创建单例
    +(instancetype)shareManager;
    //定义三个必要的属性,这里使用懒加载
    //mo上下文
    @property(nonatomic,strong,readonly)NSManagedObjectContext *managedObjectContext;
    //mo模型
    @property(nonatomic,strong,readonly)NSManagedObjectModel *managedObjectModel;
    //协调器
    @property(nonatomic,strong,readonly)NSPersistentStoreCoordinator *persistentStoreCoordinator;
    //保存上下文方法
    -(void)saveContext;
    
    /*
     对数据的
     增加 -add
     删  -delete
     改  -updata
     查  -fentch
     */
    
    //自定义一个方法,其中的操作就是通过实体名插入你想要的数据
    -(NSManagedObject *)addManagerObjectWithEntityname:(NSString *)entity;
    //查询方法,需要谓词,排序方式
    -(NSArray *)fentchEntityName:(NSString *)entityName predicate:(NSPredicate *)predicate orderby:(NSArray *)sortDescriptors;
    
    
    
    

    .m实现

    //
    //  CoreDataManager.m
    //  CoreData-demo
    //
    //  Created by mac on 16/8/19.
    //  Copyright © 2016年 mac. All rights reserved.
    //
    
    #import "CoreDataManager.h"
    //定义一个单例对象
    static CoreDataManager *instance = nil;
    
    @implementation CoreDataManager
    //单例方法实现
    +(instancetype)shareManager{
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            instance = [[CoreDataManager alloc] init];
        });
            return instance;
    }
    //等效属性--因为只有get方法
    @synthesize managedObjectModel = _managedObjectModel;
    @synthesize managedObjectContext = _managedObjectContext;
    @synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
    
    //1.模型文件对象
    -(NSManagedObjectModel *)managedObjectModel{
        //懒加载
        if (_managedObjectModel != nil) {
            return _managedObjectModel;
        }
        //获取到自己创建的coredatamodel文件的路径
        NSURL *modelUrl = [[NSBundle mainBundle]URLForResource:@"CoreDataModel" withExtension:@"momd"];//后缀名
        _managedObjectModel = [[NSManagedObjectModel alloc]initWithContentsOfURL:modelUrl];
        return _managedObjectModel;
    }
    
    //2.创建协调器
    -(NSPersistentStoreCoordinator *)persistentStoreCoordinator{
        if (_persistentStoreCoordinator !=nil) {
            return _persistentStoreCoordinator;
        }
        _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];//PS:这里需要点语法
        
        //数据库的存储路径
        NSURL *storeUrl = [NSURL fileURLWithPath:[NSHomeDirectory() stringByAppendingString:@"/Documents/Database.sqlite"]];
        
        NSError *error = nil;
        NSString *failureReason = @"There was an error creating or loading the application's saved data.";
        //给协调器添加一个可持久化的对象
        NSPersistentStore *persistentStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                                                       configuration:nil
                                                                                                 URL:storeUrl
                                                                                             options:nil
                                                                                               error:&error];
        
        if (!persistentStore) {
            //有错误
            // Report any error we got.
            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];
            // Replace this with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            //abort()会是app退出,然后生成一个崩溃日志
            //在开发阶段使用ok,但是发布的时候要注释掉.
            abort();
        }
        return _persistentStoreCoordinator;
    }
    //3.上下文
    -(NSManagedObjectContext *) managedObjectContext{
        if (_managedObjectContext !=nil) {
            return _managedObjectContext;
        }
        //拷贝一份协调器
        NSPersistentStoreCoordinator *psc = [self persistentStoreCoordinator];
        //判断是否为空
        if (!psc) {
            return nil;
        }
        //创建对象,并设置操作类型,在主队列
        _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
        //协调器
        _managedObjectContext.persistentStoreCoordinator = psc;
        
        return _managedObjectContext;
    }
    
    //方法实现,当存储数据需要改变时调用  --增加,删除,更新操作
    -(void)saveContext{
        NSManagedObjectContext *context = self.managedObjectContext;
        if (context != nil) {
            NSError *error = nil;
            if ([context hasChanges] && ![context save:&error]) {
                //如果context发生变化,会发生crash
                NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
                abort();
            }
            //如果context没有发生变化,不会进入...
        }
    }
    

    还需要在.m中实现插入和查询方法,但是我们在使用fetchedResultContoller的时候无需用到查询方法

    //添加
    -(NSManagedObject *)addManagerObjectWithEntityname:(NSString *)entity{
        //插入
        NSManagedObject *manageObject = [NSEntityDescription insertNewObjectForEntityForName:entity inManagedObjectContext:self.managedObjectContext];
        //返回一个MO对象,进行自定义操作
        return manageObject;
    }
    
    -(NSArray*)fentchEntityName:(NSString *)entityName predicate:(NSPredicate *)predicate orderby:(NSArray *)sortDescriptors{
        //抓取请求
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        //实体对象
        NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:self.managedObjectContext];
        [fetchRequest setEntity:entity];
        // Specify criteria for filtering which objects to fetch
        //使用自己定义谓词
        [fetchRequest setPredicate:predicate];
        // Specify how the fetched objects should be sorted
        //使用自己定义的排序操作
        [fetchRequest setSortDescriptors:sortDescriptors];
        
        NSError *error = nil;
        NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
        if (fetchedObjects == nil) {
            NSLog(@"error");
        }
        //返回查询到的数组
        return fetchedObjects;
    }
    
    
    

    实战演练:通过在tableview的来调用数据库中的内容,做到添加内容的效果。
    两个界面:一个tableview 一个添加内容的界面

    tableview界面:这里只是实现了添加内容进入数据库的效果,通过fetchedResultController的抓取来实现的。

    
    #import "ViewController.h"
    #import "CoreDataManager.h"
    #import "Hunter.h"
    @interface ViewController ()<UITableViewDataSource,UITableViewDelegate,NSFetchedResultsControllerDelegate>{
        //抓取结果控制器--返回的结果都在这里面
        NSFetchedResultsController *fetchedResults;
    }
    @property (weak, nonatomic) IBOutlet UITableView *myTableView;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        NSLog(@"%@",NSHomeDirectory());
        self.myTableView.delegate = self;
        self.myTableView.dataSource = self;
        [self loadData];
        
    }
    -(void)loadData{
        CoreDataManager *manager = [CoreDataManager shareManager];
        //抓取请求
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Hunter"];//实体名
        //可以选择写
        fetchRequest.predicate = nil;
        //必写
        NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES];
        fetchRequest.sortDescriptors = @[sort];
        
        //作用:抓取最终的结果
        //(1)抓取结果
        fetchedResults = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                                             managedObjectContext:manager.managedObjectContext
                                                               sectionNameKeyPath:nil
                                                                        cacheName:nil];
        //调用代理
        fetchedResults.delegate = self;
        //(2)执行查询的数据
        NSError *error = nil;
        //这时候fetchResults中就有结果了
        [fetchedResults performFetch:&error];
        
    
    }
    
    #pragma mark -dataSource , delegate
    //组数
    -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
        return fetchedResults.sections.count;
    }
    //行数
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
        return [[fetchedResults.sections objectAtIndex:section]numberOfObjects];
    }
    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellID"];
        if (cell ==nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cellID"];
        }
        //取出对象
        Hunter *model = [fetchedResults objectAtIndexPath:indexPath];
        //输出两个值
        cell.textLabel.text = model.name;
        //model.age是nsnumber类型
        cell.detailTextLabel.text = [NSString stringWithFormat:@"%d", model.age];
        
        return cell;
    }
    #pragma mark - fetchedResultsController 代理
    /*
     controller:NSFetchedResultsController对象
     ChangeObject:修改的对象
     indexPath: 对象在数据库中的位置
     ChangeType:修改的类型
     */
    //监听数据库中的变化
    -(void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath{
        if (type == NSFetchedResultsChangeInsert) {
            //刷新tableview
            [self.myTableView reloadData];
        }
    }
    
    
    @end
    
    

    添加内容界面,只需要把内容添加的数据库即可

    //
    //  AddDataViewController.m
    //  CoreData-demo
    //
    //  Created by mac on 16/8/19.
    //  Copyright © 2016年 mac. All rights reserved.
    //
    
    #import "AddDataViewController.h"
    #import "CoreDataManager.h"
    #import "Hunter.h"
    @interface AddDataViewController ()
    @property (weak, nonatomic) IBOutlet UITextField *nameText;
    @property (weak, nonatomic) IBOutlet UITextField *ageText;
    @property (weak, nonatomic) IBOutlet UITextField *heightText;
    @property (weak, nonatomic) IBOutlet UITextField *workText;
    
    @end
    
    @implementation AddDataViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
    }
    - (IBAction)buttonAction:(UIButton *)sender {
        CoreDataManager *manager = [CoreDataManager shareManager];
        Hunter *model = (Hunter *)[manager addManagerObjectWithEntityname:@"Hunter"];
        
        model.name = self.nameText.text;
        model.age = [self.ageText.text intValue];
        model.height = [self.heightText.text floatValue];
        model.work = self.workText.text;
        //保存
        [manager saveContext];
        
        [self.navigationController popViewControllerAnimated:YES];
        
    }
    
    
    @end
    
    
    1.png
    2.png
    3.png
    4.png

    相关文章

      网友评论

        本文标题:CoreData的使用以及结果的抓取

        本文链接:https://www.haomeiwen.com/subject/binbsttx.html