服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - iOS App中数据管理框架Core Data的基本数据操作教程

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

2021-01-21 15:09珲少 IOS

Core Data框架能够为我们提供比操作SQL关系型数据库更简单的数据管理方式,而且内置于Xcode中配合IDE操作十分方便,下面我们就来看一下iOS App中数据管理框架Core Data的基本数据操作教程

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

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

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

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

这时,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];
   
}

效果如下:

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

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

//数据将要改变时调用的方法
- (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];
}

延伸 · 阅读

精彩推荐
  • IOSIOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解

    这篇文章主要介绍了IOS开发之字典转字符串的实例详解的相关资料,希望通过本文能帮助到大家,让大家掌握这样的方法,需要的朋友可以参考下...

    苦练内功5832021-04-01
  • IOSIOS 屏幕适配方案实现缩放window的示例代码

    IOS 屏幕适配方案实现缩放window的示例代码

    这篇文章主要介绍了IOS 屏幕适配方案实现缩放window的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    xiari5772021-06-01
  • IOSiOS 雷达效果实例详解

    iOS 雷达效果实例详解

    这篇文章主要介绍了iOS 雷达效果实例详解的相关资料,需要的朋友可以参考下...

    SimpleWorld11022021-01-28
  • IOSiOS布局渲染之UIView方法的调用时机详解

    iOS布局渲染之UIView方法的调用时机详解

    在你刚开始开发 iOS 应用时,最难避免或者是调试的就是和布局相关的问题,下面这篇文章主要给大家介绍了关于iOS布局渲染之UIView方法调用时机的相关资料...

    windtersharp7642021-05-04
  • IOSiOS通过逆向理解Block的内存模型

    iOS通过逆向理解Block的内存模型

    自从对 iOS 的逆向初窥门径后,我也经常通过它来分析一些比较大的应用,参考一下这些应用中某些功能的实现。这个探索的过程乐趣多多,不仅能满足自...

    Swiftyper12832021-03-03
  • IOS关于iOS自适应cell行高的那些事儿

    关于iOS自适应cell行高的那些事儿

    这篇文章主要给大家介绍了关于iOS自适应cell行高的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    daisy6092021-05-17
  • IOS解析iOS开发中的FirstResponder第一响应对象

    解析iOS开发中的FirstResponder第一响应对象

    这篇文章主要介绍了解析iOS开发中的FirstResponder第一响应对象,包括View的FirstResponder的释放问题,需要的朋友可以参考下...

    一片枫叶4662020-12-25
  • IOSiOS中tableview 两级cell的展开与收回的示例代码

    iOS中tableview 两级cell的展开与收回的示例代码

    本篇文章主要介绍了iOS中tableview 两级cell的展开与收回的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    J_Kang3862021-04-22