简体   繁体   中英

Having to call fetch twice from CoreData

Both on simulator and my real device, an array of strings is saved upon app termination. When I restart the app and fetchRequest for my persisted data (either from a viewDidLoad or a manual button action), I get an empty array on the first try. It isn't until the second time I fetchRequest that I finally get my data.

The funny thing is that there doesn't seem to be a time discrepancy involved in this issue. I tried setting various timeouts before trying to fetch the second time. It doesn't matter whether I wait 10 seconds to a minute -- or even immediately after the first fetch; the data is only fetched on the second try.

I'm having to use this code to fetch my data:

        var results = try self.context.fetch(fetchRequest) as! [NSManagedObject]
        while (results.isEmpty) {
            results = try self.context.fetch(fetchRequest) as! [NSManagedObject]
        }
        return results

For my sanity's sake, here's a checklist:

Note** I forgot to mention that I'm building a framework. I am using CoreData with the framework's bundle identifier and using the model contained in the framework, so I want to avoid having to use logic outside of the framework (other than initalizing the framework in the appDelegate).

应该在位于appDelegate.swift中的applicationDidFinishLaunchingWithOptions中初始化Core Data堆栈,因为在尝试获取数据后会添加psc。

That boilerplate code from Apple includes:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
    /* ... */
    do {
        try psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil)
    } catch {
        fatalError("Error migrating store: \(error)")
    }
}

The saved data isn't available until the addPersistentStoreWithType call finishes, and that's happening asynchronously on a different queue. It'll finish at some point but your code above is executing before that happens. What you're seeing isn't surprising-- you're basically looping until the async call finishes.

You need to somehow delay your fetch until the persistent store has been loaded. There are a couple of possibilities:

  1. Do something sort of like what you're already doing. I'd prefer to look at the persistent store coordinator's persistentStores property to see if any stores have been loaded rather than repeatedly trying to fetch.
  2. Post a notification after the persistent store is loaded, and do your fetch when the notification happens.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM