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

Core Data的框架_第1张图片
示意图

对原有的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里有如图的


Core Data的框架_第2张图片
示意图

每个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----

你可能感兴趣的:(Core Data的框架)