NSFetchedResultsController无法更新tableView swift4

时间:2018-09-25 07:10:05

标签: core-data swift4 nsfetchedresultscontroller

我正在尝试使其在最近几天内无法使用。我似乎似乎找不到它的一些小细节。 您能否看一下,并给我一些有关我的代码的见解? 我正在尝试使用coredata中的应用程序保存来更新logView。 这是ViewController和CoreData Handler的完整代码。

/// fetch controller
lazy var fetchController: NSFetchedResultsController = { () -> NSFetchedResultsController<NSFetchRequestResult> in
    let entity = NSEntityDescription.entity(forEntityName: "Logs", in: CoreDataHandler.sharedInstance.backgroundManagedObjectContext)
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>()
    fetchRequest.entity = entity

    let nameDescriptor = NSSortDescriptor(key: "name", ascending: false)
    fetchRequest.sortDescriptors = [nameDescriptor]

    let fetchedController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: CoreDataHandler.sharedInstance.backgroundManagedObjectContext, sectionNameKeyPath: "duration", cacheName: nil)
    fetchedController.delegate = self as? NSFetchedResultsControllerDelegate
    return fetchedController
}()

override func viewDidLoad() {
    title = "Week Log"

    tableView.tableFooterView = UIView(frame: CGRect.zero)
    tableView.separatorColor = UIColor.black
    tableView.backgroundColor = UIColor.red

    refreshView()
    loadNormalState()
    loadCoreDataEntities()

}


/**
 Refresh the view, reload the tableView.
 */
func refreshView() {
    loadCoreDataEntities()
    tableView.reloadData()
}



/**
 Load history entities from core data. (I'm printing on the console and
 be able to see the the fetched data but I can't load it to tableView.)
 */

func loadCoreDataEntities() {

        do {
            try fetchController.performFetch()
        } catch {
            print("Error occurred while fetching")
        }
}

import Foundation
import CoreData

class CoreDataHandler: NSObject {

/**
 Creates a singleton object to be used across the whole app easier

 - returns: CoreDataHandler
 */
class var sharedInstance: CoreDataHandler {
    struct Static {
        static var instance: CoreDataHandler = CoreDataHandler()
}
    return Static.instance
}


lazy var backgroundManagedObjectContext: NSManagedObjectContext = {
    let backgroundManagedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
    let coordinator = self.persistentStoreCoordinator
    backgroundManagedObjectContext.persistentStoreCoordinator = coordinator
    return backgroundManagedObjectContext
}()

lazy var objectModel: NSManagedObjectModel = {
    let modelPath = Bundle.main.url(forResource: "Model", withExtension: "momd")
    let objectModel = NSManagedObjectModel(contentsOf: modelPath!)
    return objectModel!
}()

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
    let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.objectModel)

    // Get the paths to the SQLite file
    let storeURL = self.applicationDocumentsDirectory().appendingPathComponent("Model.sqlite")

    // Define the Core Data version migration options
    let options = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true]

    // Attempt to load the persistent store
    var error: NSError?

    var failureReason = "There was an error creating or loading the application's saved data."
    do {
        try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: options)
    } catch {
        // Report any error we got.
        var dict = [String: AnyObject]()
        dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" as AnyObject
        dict[NSLocalizedFailureReasonErrorKey] = failureReason as AnyObject

        dict[NSUnderlyingErrorKey] = error as NSError
        let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
        // Replace this with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
        NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
        abort()
    }
    return persistentStoreCoordinator
}()

func applicationDocumentsDirectory() -> NSURL {
    return FileManager.default.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask).last! as NSURL
}

func saveContext() {
    do {
        try backgroundManagedObjectContext.save()
    } catch {
        print("Error while saving the object context")
        // Error occured while deleting objects
    }
}

1 个答案:

答案 0 :(得分:0)

您在某处有一个数据源代理。该数据源代理告诉表视图有多少个项目,以及它们的内容是什么。它怎么知道多少个项目?那必须存放在某个地方。

获取控制器成功后,它必须以某种方式修改数据源委托所依赖的数据,然后调用reloadData。你在做这个吗?您是否正在做任何导致数据源委托更改其报告项目数量的事情?

并先调用loadCoreDataEntities,然后再调用reloadData是胡说八道。 loadCoreDataEntities是异步的。在您调用reloadData时,它尚未加载任何实体。当loadCoreDataEntities完成时,将调用realodData。