Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >「死磕」Core Data——非标准数据类型的保存

「死磕」Core Data——非标准数据类型的保存

作者头像
iOS Development
发布于 2019-02-14 09:49:09
发布于 2019-02-14 09:49:09
1K00
代码可运行
举报
运行总次数:0
代码可运行

上一篇写了Core Data的入门,这篇会涉及两部分内容:

  • NSFetchedResultsController的使用。
  • 非标准数据类型的保存。

NSFetchedResultsController的使用

其实这个名字,会引起一定的歧义,光看名字,以为是一个普通的视图控制器,其实它并不继承自UIViewController类。

这个类,仅用于高效地管理从Core Data中取回的数据,供UITableView使用,也就是作为UITableView的数据源而存在的。可能是UITableView在iOS开发中太常用了,所以专门造了这个类,和UITableView搭配使用。

创建一个NSFetchedResultsController

需要使用NSFetchedResultsController,首先初始化,创建一个NSFetchedResultsController对象:

(在这段代码之前,我们已经声明了一个属性@property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- (void)initializeFetchedResultsController {

    // 这里的kUserEntityName就是你在xcdatamodeld文件的实体名称。
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:kUserEntityName];
    
    // 返回数据的排序规则(最少需要有一个sort descriptor)
    // Need at least one sort descriptor
    NSSortDescriptor *nameSort = [NSSortDescriptor sortDescriptorWithKey:kUserNameKey ascending:YES];
    
    [request setSortDescriptors:@[nameSort]];
    
    // 实例化fetchedResultsController对象
    // 需要利用在此之前已经创建的NSManagedObjectContext对象
    // 最后一个参数,可以复制一个字符串,Core Data会自己设置缓存,以提升性能。
    [self setFetchedResultsController:[[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:[SPKManager shareManager].store.context sectionNameKeyPath:nil cacheName:nil]];

     // 设置委托对象
     // 协议中有4个委托方法,用来告诉UITableView,Core Data中的数据有变化
    [self.fetchedResultsController setDelegate:self];
    
    NSError *error = nil;
    if (![[self fetchedResultsController] performFetch:&error]) {
        NSLog(@"Failed to initialize FetchedResultsController: %@\n%@", [error localizedDescription], [error userInfo]);
        abort();
    }
}

以上的初始化方法,会放在UITableViewController类中进行。

为Table View提供数据源

要告诉Table View有多少行数据,利用NSFetchedResultsController的sections属性。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    
    id<NSFetchedResultsSectionInfo>sectionInfo = self.fetchedResultsController.sections[section];
    return [sectionInfo numberOfObjects];
}

要拿回具体的某个对象,利用NSFetchedResultsController的objectAtIndexPath:方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SPKUser *user = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = user.userName;
cell.detailTextLabel.text = [NSString stringWithFormat:@"%@", @(user.userID)];

// 如果没有自定义NSManagedObject子类,就应该类似:NSManagedObject *object = [self.fetchedResultsController objectAtIndexPath:indexPath];
监视数据的变化

当Core Data中的数据发生变化时,可以通过 NSFetchedResultsControllerDelegate中的委托方法,方便监视数据的变化,自动更新UI

实现协议的四个方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#pragma mark - NSFetchedResultsControllerDelegate
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller{
    [_tableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
    switch (type) {
        case NSFetchedResultsChangeInsert:
              // 插入了section
            [_tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
            
        case NSFetchedResultsChangeDelete:
              // 删除了section
            [_tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
            
        case NSFetchedResultsChangeMove:
            break;
            
        case NSFetchedResultsChangeUpdate:
            break;
            
        default:
            break;
    }
}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
    switch (type) {
        case NSFetchedResultsChangeInsert:
            // 插入了新对象
            [_tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
            
        case NSFetchedResultsChangeDelete:
              // 删除了对象
            [_tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
            
        case NSFetchedResultsChangeUpdate:
            // 修改了对象
            [self configureCell:[_tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;
            
        case NSFetchedResultsChangeMove:
              // 移动了对象 
            [_tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [_tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
            
        default:
            break;
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    [_tableView endUpdates];
}

非标准数据类型的处理

在Core Data中,可以保存数据类型比较有限:

  • Integer 16
  • Integer 32
  • Integer 64
  • Decimal (高精度大数,不会四舍五入,适用于金融领域)
  • Double
  • Float
  • String
  • Boolean
  • Date
  • Binary Data
  • Transformable

如果是非标准数据类型,如何保存?

UIImage、UIColor

UIImage和UIColor这类遵守了NSCoding协议的对象,Core Data会帮你转换为NSData后,保存,取回来,也会帮你从NSData转为相对应的对象。选择Transformable类型即可,

数组,字典

NSArray、NSMutableArray、NSDictionary、NSMutableDictionary也是遵守NSCoding的对象,也可以选择Transformable直接保存。

当然,也可以选择Binary Data

  • 保存前,调用NSKeyedUnarchiver的archivedDataWithRootObject:方法返回NSData类型数据,让Core Data可以对其进行保存;
  • 取回时,用NSKeyedUnarchiver的unarchiveObjectWithData:方法,将取回的NSData数据,转换回数组、字典对象。
结构体

保存结构体,可以选择Transformable类型。

然后在声明属性类型的时候,使用NSValue类型,如@property (nullable, nonatomic, retain) NSValue *imgeRect;

赋值时,进行转化,如下: newUser.imgeRect = [NSValue valueWithCGRect:CGRectMake(0.0, 0.0, 100.0, 100.0)];

获取值的时候,再进行转换,如下: CGRect imageRect = [firstUser.imgeRect CGRectValue];

枚举类型

两种思路:

  • 选择Integer 16,当作一个整数机型保存。(声明的时候,就可以用枚举类型了)。如@property (nonatomic) UserGenderType userGender;
  • 选择Transformable,然后重写get、set方法,进行转换……还是用上面的方法吧,比较简单:)

自定义对象

自定义对象,也有两种思路:

  • 直接定义成xcdatamodeld文件中的一个实体,作为NSManagedObject类的子类,由CoreData直接保存;
  • 如果不定义成实体,需要:
  • 该自定义对象需要遵守NSCoding协议并实现required方法(initWithCoder:方法和encodeWithCoder:方法);
  • xcdatamodeld文件中该特性数据类型选择为Transformable
  • 创建一个NSValueTransformer子类,重写transformedValue:和reverseTransformedValue:方法,手动进行数据类型的转换(本质就是自定义对象和NSData互转)类似如下:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#import "HAEqTransformer.h"
#import "HAEq.h"

// 我的自定义对象是HAEq
@implementation HAEqTransformer

+ (Class)transformedValueClass {
    return [NSData class];
}

- (id)transformedValue:(id)value {
    if (!value) {
        return nil;
    }
    
    if ([value isKindOfClass:[NSData class]]) {
        return value;
    }
    
    HAEq *eq = (HAEq *)value;
    // 将自定义对象转换成NSData
    NSData *dataFromEq = [NSKeyedArchiver archivedDataWithRootObject:eq];
    
    return dataFromEq;
}

- (id)reverseTransformedValue:(id)value {
    NSData *data = (NSData *)value;
    // 将NSData对象转换为自定义对象
    HAEq *eq = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    return eq;
}
@end

所以,利用Core Data保存非标准数据类型,以上都基本涉及了。

End

以上,就是Core Data中的NSFetchedResultsController的使用、以及非标准数据类型的保存方法。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.05.06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
iOS中CoreData数据管理系列四——进行数据与页面的绑定
    在上一篇博客中,我们讨论了CoreData框架中添加与查询数据的操作,事实上,在大多数情况下,这些数据都是由一个UITableView表视图进行展示的,因此,CoreData框架中还未开发者提供了一个类NSFetchedResultsController,这个类作为桥接,将视图与数据进行绑定。
珲少
2018/08/15
7230
iOS中CoreData数据管理系列四——进行数据与页面的绑定
IOS开发之新浪围脖
  IOS开发和Web开发一样,网络请求方式包括Get和Post方式。Get和Post两者有和特点和区别,在本篇博客中不做过多的论述,本篇的重点在于如何GET数据和POST数据。下面还会提到如何在我们的项目中使用CocoaPods, CocoaPods的安装和使用教程请参考链接http://code4app.com/article/cocoapods-install-usage。上面详细的介绍了CocoaPods的安装过程和如何通过CocoaPods引入第三方类库。在本篇博客中提到CocoaPods,是因为
lizelu
2018/01/11
1.3K0
IOS开发之新浪围脖
iOS - 模型数据持久化保存实现
image.png 在iOS开发实际中,可以在 AppDelegate.m 的 didFinishLaunchingWithOptions方法中,快速定位需要当前需要开发的控制器 但是,如果要开发的控制器,需要之前的控制器传值怎么办呢? image.png ==> 解决办法 : 方法1:不设置rootVC = 当前开发控制器(TwoVC),默认使用homeVC,一步一步点击,似魔鬼的步伐一般进入TwoVC 方法2 :还是设置rootVC = 当前的开发控制器(TwoVC),同时,使用数据持久化保存,保存
小蠢驴打代码
2018/05/24
2K0
iOS面向切面的TableView-AOPTableView
这个是公司很久之前的开源项目,一个大牛写的,在项目中一直有在用,今天有空发了点时间看下如何实现,看了之后感觉挺有收获,故撰此文,分享给需要的同学。
iOSSir
2019/05/11
1K0
Swift 定制 Core Data 迁移
随着应用程序和用户群的增长,你需要添加新功能,删除其他功能,并改变应用程序的工作方式。这是软件开发生命周期的自然结果,我们应该接受。
Swift社区
2024/08/03
870
Swift 定制 Core Data 迁移
iOS开发之表视图爱上CoreData
  在接触到CoreData时,感觉就是苹果封装的一个ORM。CoreData负责在Model的实体和sqllite建立关联,数据模型的实体类就相当于Java中的JavaBean, 而CoreData的功能和JavaEE中的Hibernate的功能类似,最基本是两者都有通过对实体的操作来实现对数据库的CURD操作。CoreData中的上下文(managedObjectContext)就相当于Hibernate中的session对象, CoreData中的save操作就和Hibernate中的commit,还
lizelu
2018/01/11
2.2K0
iOS开发之表视图爱上CoreData
「死磕」Core Data——入门
因为我是文科狗转行的程序猿,并没有学过数据库相关课程,也欣赏不出SQLite的美,所以之前的项目一直用NSKeyedArchiver和NSKeyedUnarchiver(固化)进行数据的本地保存(所幸我接触的项目,数据都不会太复杂)。
iOS Development
2019/02/14
1.2K0
【死磕iOS】处理不等高TableViewCell的小花招
地址://www.jianshu.com/p/a0342ee86431 嗨大家,好久不见~ 今天来和大家一起聊聊处理不等高TableViewCell的那些小花招~ ummmm…其实我是个标题党~ ??
春哥大魔王
2018/04/16
1.3K0
【死磕iOS】处理不等高TableViewCell的小花招
Swift实践:使用CoreData存储多种数据类的通讯录1. CoreData支持存储数据类型2. 使用CoreData存储多种数据类的通讯录3. Codable
看了一看上一篇文章的更新时间,已经可以追溯到两个月前了。确实又是满怀愧疚的更新这一篇文章。 最近这一个月新开了一个Swift自习室,没想到瞬间就满了40个人,心里面还是有点小小的激动的。辣么多人可以一
stanbai
2018/06/28
2.1K0
UITableView 编辑状态(删除、添加、移动)
----- TableView 删除和添加 ----- ** UITableView 编辑步骤 1.让 tableView 处于编辑状态 2.协议确定 1)确定 cell 是否处于编辑状态 2)设定 cell 的编辑样式(删除、添加) 3) 编辑状态进行提交** 开启编辑状态 //1.让 tableView 处于编辑状态 [tableView setEditing:YES animated:YES]; 如果
LeeCen
2018/10/11
1.5K0
UITableView 编辑状态(删除、添加、移动)
更轻量的 View Controllers
View controllers 通常是 iOS 项目中最大的文件,并且它们包含了许多不必要的代码。所以 View controllers 中的代码几乎总是复用率最低的。我们将会看到给 view controllers 瘦身的技术,让代码变得可以复用,以及把代码移动到更合适的地方。
用户5290428
2019/05/06
5590
iOS开发·第三方数据库处理框架:Realm 基本用法
除了FMDB,Realm也是一种很流行的数据库方案。 1. 官方资料 (最新版)Realm Objective‑C官方文档地址 https://realm.io/docs/objc/latest/ (中文版)Realm Objective‑C官方文档地址(内容相对英文版不一定是最新的)https://realm.io/cn/docs/objc/latest/ Realm官方API查阅手册 https://realm.io/docs/objc/latest/api/ GitHub源码地址 http
陈满iOS
2018/09/10
1.1K0
归档
归档 基本概念 - 对象归档是指将对象写入文件保存在硬盘上,当再次重新打开程序时,可以还原这些对象。你也可以称他为对象序列化,对象持久化。 数据持久性的方式 NSKeyedArchiver --- 对象归档 NSUserDefaults 属性列表化(NSArray、NSDictionary保存文件) SQlite数据库、Core Data数据库 归档的形式 对Foundation库中对象进行归档 自定义对象进行归档(需要实现归档协议,NSCoding) 归档后的文件是加密的,属性列表是明文的。属性列表也不
用户1941540
2018/05/11
1.2K0
iOS开发——数据持久化之归档
在实际的项目开发中,数据持久化是我们必须要考虑的一个事情,如何把我们需要的数据进行持久化处理。
Originalee
2018/08/30
6220
iOS数据持久化之二——归档与设计可存储化的数据模型基类
        在上一篇博客中,我们介绍了用plist文件进行数据持久化的方法。虽然简单易用,但随着开发的深入,你会发现,这种方式还是有很大的局限性。试想,如果我们可以将用户的登录返回信息模型,游戏中角色的属性信息模型进行直接的持久化存取,那是不是非常爽的事,幸运的是,我们可以通过归档,来设计一个这样的数据模型。
珲少
2018/08/16
1.1K0
iOS数据持久化之二——归档与设计可存储化的数据模型基类
DTCoreText的集成与使用目录一、相关资源二、DTCoreText的集成三、DTCoreText的使用四、可能遇到的错误五、参考链接
DTCoreText是可以将HTML字符串转化为富文本使用的工具,既保证原生实现又能适应灵活的样式修改,而且相比于使用WebView显示内容在性能上也有很大优势。本篇就这一技术的使用进行总结。 目录 一、相关资源 二、DTCoreText的集成 三、DTCoreText的使用 四、可能遇到的错误 五、参考链接 一、相关资源 DTCoreText源码下载 DTCoreText官方文档 DTCoreText集成文档 本文DTCoreText测试工程 温馨提示:文中代码量比较大,看起来可能比较费劲,所以先
梧雨北辰
2018/04/24
5K0
DTCoreText的集成与使用目录一、相关资源二、DTCoreText的集成三、DTCoreText的使用四、可能遇到的错误五、参考链接
UITableView进阶:常用代理方法及属性1. 常用属性2. 进阶的常用代理方法
在前面的文章里面已经写过了“UITableView基础”,所以这篇里面就不再对这里面的内容进行介绍。如果有幸去瞄一眼的,可以通过文章下面的拓展链接传送门去看。& 今天重点聊一聊UITableView中经常使用到的代理方法及属性。本文不是工具箱,所以不会将所有的属性和方法都写下来噢。只是总结经常使用到的。太完整的也记不住,真的是要用的时候临时翻一下.h文件看看也行。 1. 常用属性 1.1 分隔线属性 属性名称 数值 作用 separatorStyle UITableViewCellSeparatorStyl
stanbai
2018/06/28
1.2K0
【IOS开发基础系列】数据持久化专题
iOS中可以有四种持久化数据的方式: 属性列表、对象归档、SQLite3和Core Data。
江中散人_Jun
2023/10/16
3690
【IOS开发基础系列】数据持久化专题
如何结合 Core Data 和 SwiftUI
SwiftUI 和 Core Data 之间相差将近十年 —— SwiftUI 随着 iOS 13 面世而 Core Data 则是 iPhoneOS 3 的产物;很久以前,它还没有被称为 iOS,因为 iPad 尚未发布。尽管时间相距遥远,Apple 还是投入了大量工作以确保这两种强大的技术能够完美地相互配合使用,这意味着 Core Data 就像始终以这种方式设计一样,已集成到 SwiftUI 中。
Swift社区
2021/11/26
11.8K0
如何结合 Core Data 和 SwiftUI
Core Data 基础
Core Data 是 iOS SDK 里的一个很强大的框架,允许程序员以面向对象的方式储存和管理数据
CC老师
2023/03/23
1.1K0
Core Data 基础
推荐阅读
相关推荐
iOS中CoreData数据管理系列四——进行数据与页面的绑定
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验