Core Data的框架

iOS Persistence and Core Data Lesson 5 - Udacity的笔记

笔记目录:
1.保存数据的基础知识
2.如何使用NSCoder/NSKeyedArchiver保存数据
3.Core Data的使用
4.Core Data的构建
5.Core Data的框架(所在章节)
各文章的介绍:我的女朋友CoreData和她闺蜜们


Smart Architecture w/Core Data

前言

终于写到iOS Persistence and Core Data的最后一篇笔记了。试着跟别人解释这样写笔记能令自己对一些知识看得透彻一点。因为不断假设:"假如别人这么问,我应该怎么答呢?"于是不断问自己问题,不断解答,强迫自己思考


把最后的感言写在这里,那么剩下的全都是技术

最后

终于把这文章写完了,第一次通过一问一答的形式,进行做这个笔记,自我感觉不错。以前,看数学书时,笛卡尔就提过“将大问题分成若干个小问题,再一个一个解决”

当Model(数据)更新的时候,View Controller如何知道Model更新了?

Core Data 推荐以下两种方式:
1.Notification Center
2.NSFetchResultsController
这篇文章就是介绍如何使用的NSFetchResultsController

NSFetchResultsController扮演的是什么角色?

如图,MovieDB是服务器,FetchController就是通知Master Controller数据是否有更新 ,然后将数据从Core DataContext传递给Master Controller

示意图

对原有的Project怎么替换为NSFetchResultsController?

Project要利用NSFetchResultsController两个特性:获取与通知。则产生如下两个问题:

1.如何获取Context里的数据
2.NSFetchResultsController如何通知Controller

先来解决第一个问题

如何获取Context里的数据

如上面的图,问题拆分为两个:

1.NSFetchResultsController怎么从Context当中获取数据
2.Controller如何从NSFetchedResultsController中获取数据?

获取Core Data保存的数据
原有的Project从Context直接取出数据,而这里则是通过NSFetchResultsController获取数据.

那么NSFetchResultsController怎么从Context当中获取数据?
1.设置NSFetchRequest
2.设置NSFetchedResultsController
代码如下:

lazy var fetchedResultsController: NSFetchedResultsController = {
    
    // Create the fetch request
    let fetchRequest = NSFetchRequest(entityName: "Event")
    
    // Add a sort descriptor.
    fetchRequest.sortDescriptors = [NSSortDescriptor(key: "timeStamp", ascending: false)]
    
    // Create the Fetched Results Controller
    let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.sharedContext, sectionNameKeyPath: nil, cacheName: nil)
    
    // Return the fetched results controller. It will be the value of the lazy variable
    return fetchedResultsController
    } ()

然后只需在恰合的地方,譬如viewDidLoad,使用以下代码就能让NSFetchedResultsController获取到数据。

do {
    try fetchedResultsController.performFetch()
} catch {
    print("Unresolved error \\\\(error)")
    abort()
}

接下来Controller如何从NSFetchedResultsController中获取数据?
Object

let event = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Event

Objects数量

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    let sectionInfo = self.fetchedResultsController.sections![section]
    return sectionInfo.numberOfObjects
}

NSFetchResultsController如何通知Controller

通过delegate,其中delegate method有一下四个本lesson用到的:英文就不翻译了,因为感觉更符合

"I am about to tell you about some changes"
controllerWillChangeContent(_:)

"An object changed (an Event was inserted, removed, or altered)"
controller(_:didChangeObject:atIndexPath:forChangeType:newIndexPath:)

"Your table’s sections should change"
controller(_:didChangeSection:atIndex:forChangeType:)

"I am done telling you about changes for now"
controllerDidChangeContent(_:)

那么在代码中使用是为了刷新tableView,使view重新绘制,所以代码如下:

func controllerWillChangeContent(controller: NSFetchedResultsController) {
    // This invocation prepares the table to recieve a number of changes. It will store them up
    // until it receives endUpdates(), and then perform them all at once.
    self.tableView.beginUpdates()
}

func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
    // Our project does not use sections. So we can ignore these invocations.
}

//
// This is the most important method. It adds and removes rows in the table, in response to changes in the data.
//

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
    switch type {
    case .Insert:
        tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
    case .Delete:
        tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
    default:
        return
    }
}

// When endUpdates() is invoked, the table makes the changes visible.
func controllerDidChangeContent(controller: NSFetchedResultsController) {
    self.tableView.endUpdates()
}

如果不想将Context里所有数据都取出,而是要其中的符合条件,该如何做?

例如Context里有如图的


示意图

每个Person都有专属的Moive,而现在我们想要某一Person的Moive,怎么办?
我们可以使用Predicate

let fetchRequest = NSFetchRequest(entityName:"Movie")
//过滤,返回Movie里actor = self.actor的Movie
fetchRequest.predicate = NSPredicate(format:"actor == %@",self.actor)

具体用法可以参考以下:
Predicate Programming Guide

-------END-------
---And Thank U----

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,212评论 19 139
  • 在这篇文章中,我们将建立一个小型但却全面支持 Core Data 的应用。此应用允许你创建嵌套的列表;每个列表的 ...
    评评分分阅读 3,701评论 0 5
  • 晨 地平线还泛着微光。一簇簇人聚集海边 或是佯装散步 或是摆弄镜头 像在等待着什么。终于某一时刻 集体掀起黑幕 偷...
    月亭阅读 1,369评论 0 0
  • 楠子今天说: 领导人品差,打击报复,即将离职还开部门会议把我平时工作中无关紧要的小失误亮出来,故意刁难,说态度和底...
    白小白女性生涯规划阅读 5,228评论 0 3
  • 爱美之心人皆有之!随着社会和经济发展,人们对美的追求愈加强烈,催生了繁荣的美容护肤产业,层出不穷的美容方法,给消费...
    hbinglan阅读 1,292评论 0 0

友情链接更多精彩内容