广

IOS开发

  • IOS开发
  • android开发
  • PHP编程
  • JavaScript
  • ASP.NET
  • ASP编程
  • JSP编程
  • Java编程
  • 易语言
  • Ruby编程
  • Perl编程
  • AJAX
  • 正则表达式
  • C语言
  • 编程开发

    iOS App中数据管理框架Core Data的基本数据操作教程

    2018-04-08 09:04:52 次阅读 稿源:互联网
    零七广告

    NSEntityDescription是实体描述对象,它可以类比如数据库中的表,NSEntityDescription存放的是表的结构信息。这些类都是一些抽象的结构类,并不存储实际每条数据的信息,具体的数据由NSManagedObject类来描述,我们一般会将实体类化继承于NSManagedObject。

    Xocde工具提供了快捷的实体类化功能,还拿我们一开始创建的班级与学生实体来演示,点击.xcdatamodeld文件,点击Xcode工具上方导航栏的Editor标签,选择Creat NSManagedObject Subclass选项,在弹出的窗口中勾选要类化的实体,如下图:

    这时,Xcode会自动为我们创建一个文件,这些文件中有各个类中属性的声明。

    一、创建一条数据

    使用如下代码进行数据的创建:

        //读取数据模型文件
        NSURL *modelUrl = [[NSBundle mainBundle]URLForResource:@"Model" withExtension:@"momd"];
        //创建数据模型
        NSManagedObjectModel * mom = [[NSManagedObjectModel alloc]initWithContentsOfURL:modelUrl];
        //创建持久化存储协调者
        NSPersistentStoreCoordinator * psc = [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:mom];
        //数据库保存路径
        NSURL * path =[NSURL fileURLWithPath:[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"CoreDataExample.sqlite"]];
        //为持久化协调者添加一个数据接收栈
        /*
        可以支持的类型如下:
         NSString * const NSSQLiteStoreType;//sqlite
         NSString * const NSXMLStoreType;//XML
         NSString * const NSBinaryStoreType;//二进制
         NSString * const NSInMemoryStoreType;//内存
        */
        [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:path options:nil error:nil];
        //创建数据管理上下文
        NSManagedObjectContext * moc = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSMainQueueConcurrencyType];
        //关联持久化协调者
        [moc setPersistentStoreCoordinator:psc];
        //创建数据对象
        /*
        数据对象的创建是通过实体名获取到的
        */
        SchoolClass * modelS = [NSEntityDescription insertNewObjectForEntityForName:@"SchoolClass" inManagedObjectContext:moc];
        //对数据进行设置
        modelS.name = @"第一班";
        modelS.stuNum = @60;
        //进行存储
        if ([moc save:nil]) {
            NSLog(@"新增成功");
        }
        NSLog(@"%@",[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"CoreDataExample.sqlite"]);
    找到在打印出的路径,会发现里面多了一个sqlite文件,其中有一张表中添加进了一条数据。

    二、查询数据

    CoreData中通过查询请求来对数据进行查询操作,查询请求由NSFetchRequest来进行管理和维护。

    NSFetchRequest主要提供两个方面的查询服务:

    1.提供范围查询的相关功能

    2.提供查询结果返回类型与排序的相关功能

    NSFetchRequest中常用方法如下:

    //创建一个实体的查询请求 可以理解为在某个表中进行查询
    + (instancetype)fetchRequestWithEntityName:(NSString*)entityName;
    //查询条件
    @property (nullable, nonatomic, strong) NSPredicate *predicate;
    //数据排序
    @property (nullable, nonatomic, strong) NSArray<NSSortDescriptor *> *sortDescriptors;
    //每次查询返回的数据条数
    @property (nonatomic) NSUInteger fetchLimit;
    //设置查询到数据的返回类型
    /*
    typedef NS_OPTIONS(NSUInteger, NSFetchRequestResultType) {
        NSManagedObjectResultType  = 0x00,
        NSManagedObjectIDResultType  = 0x01,
        NSDictionaryResultType          NS_ENUM_AVAILABLE(10_6,3_0) = 0x02,
        NSCountResultType    NS_ENUM_AVAILABLE(10_6,3_0) = 0x04
    };
    */
    @property (nonatomic) NSFetchRequestResultType resultType;
    //设置查询结果是否包含子实体
    @property (nonatomic) BOOL includesSubentities;
    //设置要查询的属性值
    @property (nullable, nonatomic, copy) NSArray *propertiesToFetch;
    在SchoolClass实体中查询数据,使用如下的代码:

        //创建一条查询请求
        NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"SchoolClass"];
        //设置条件为 stuNum=60的数据
        [request setPredicate:[NSPredicate predicateWithFormat:@"stuNum == 60"]];
        //进行查询操作
        NSArray * res = [moc executeFetchRequest:request error:nil];
        NSLog(@"%@",[res.firstObject stuNum]);

    进行数据初始化

        NSFetchedResultsController的初始化需要一个查询请求和一个数据操作上下文。代码示例如下:

    //遵守协议
    @interface ViewController ()<NSFetchedResultsControllerDelegate>
    {
        //数据桥接对象
        NSFetchedResultsController * _fecCon;
    }
    @end

    @implementation ViewController

    - (void)viewDidLoad {
        [super viewDidLoad];
        //进行初始化操作
        NSURL *modelUrl = [[NSBundle mainBundle]URLForResource:@"Model" withExtension:@"momd"];
        NSManagedObjectModel * mom = [[NSManagedObjectModel alloc]initWithContentsOfURL:modelUrl];
        NSPersistentStoreCoordinator * psc = [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:mom];
        NSURL * path =[NSURL fileURLWithPath:[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"CoreDataExample.sqlite"]];
        [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:path options:nil error:nil];
        NSManagedObjectContext * moc = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSMainQueueConcurrencyType];
        [moc setPersistentStoreCoordinator:psc];
        NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"SchoolClass"];
        //设置数据排序
        [request setSortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"stuNum" ascending:YES]]];
        //进行数据桥接对象的初始化
        _fecCon = [[NSFetchedResultsController alloc]initWithFetchRequest:request managedObjectContext:moc sectionNameKeyPath:nil cacheName:nil];
        //设置代理
        _fecCon.delegate=self;
        //进行数据查询
        [_fecCon performFetch:nil];
    }
    @end
    用于初始化NSFecthedResultsController的数据请求对象必须设置一个排序规则。在initWithFetchRequest:managedObjectContext:sectionNameKeyPath:cacheName:方法中,如果设置第三个参数,则会以第三个参数为键值进行数据的分区。当数据发生变化时,将通过代理进行方法的回调。

    三、与UITableView进行数据绑定

    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"cellid"];
        if (!cell) {
            cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cellid"];
        }
        //获取相应数据模型
        SchoolClass * obj = [_fecCon objectAtIndexPath:indexPath];
        cell.textLabel.text = obj.name;
        cell.detailTextLabel.text = [NSString stringWithFormat:@"有%@人",obj.stuNum];
        return cell;
    }
    -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
        return [_fecCon sections].count;
    }
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
        id<NSFetchedResultsSectionInfo> info =  [_fecCon sections][section];
        return [info numberOfObjects];
       
    }
    效果如下:

    四、将数据变化映射到视图

    //数据将要改变时调用的方法
    - (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
    {
        //开启tableView更新预处理
        [[self tableView] beginUpdates];
    }
    //分区数据改变时调用的方法
    - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
    {
        //判断行为类型
        switch(type) {
            //插入新分区
            case NSFetchedResultsChangeInsert:
                [[self tableView] insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
                break;
            //删除分区
            case NSFetchedResultsChangeDelete:
                [[self tableView] deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
                break;
            //移动分区
            case NSFetchedResultsChangeMove:
            //更新分区
            case NSFetchedResultsChangeUpdate:
                break;
        }
    }
    //数据改变时回调的代理
    - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
    {
        switch(type) {
            //插入数据
            case NSFetchedResultsChangeInsert:
                [[self tableView] insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
            //删除数据
            case NSFetchedResultsChangeDelete:
                [[self tableView] deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
            //更新数据
            case NSFetchedResultsChangeUpdate:
                [self reloadData];
                break;
            //移动数据
            case NSFetchedResultsChangeMove:
                [[self tableView] deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
                [[self tableView] insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
        }
    }
    //数据更新结束调用的代理
    - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
    {
        [[self tableView] endUpdates];
    }

    零七网部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与零七网进行文章共享合作。

    零七广告
    零七广告
    零七广告
    零七广告