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 Data的Context
传递给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----