Core Data的框架

作者: 莫威權在B612等着那温柔的风 | 来源:发表于2015-11-25 22:10 被阅读990次

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

    相关文章

      网友评论

      本文标题:Core Data的框架

      本文链接:https://www.haomeiwen.com/subject/yzfdhttx.html