UIManagedDocuemnt将无法打开

时间:2018-01-21 17:20:58

标签: ios swift core-data

我的应用程序(Xcode 9.2,Swift 4)使用UIManagedDocument作为基本核心数据堆栈。一切都运行良好好几个月,但最近我注意到几个案例,应用程序将无法为现有用户加载,因为核心数据init没有完成。这通常发生在应用程序崩溃后(我想但不确定)。

我已经能够在调试器上重新创建问题并将问题缩小到以下情况:

应用启动 - >调用核心数据启动 - > UIManagedDocument对象是init'd - >检查doc status == closed - >在doc上调用open() - > open永远不会完成 - 永远不会调用回调闭包。

我已经将UIManagedDocument子类化了,所以我可以覆盖configurePersistentStoreCoordinator()来检查它是否到达那个点,但事实并非如此。永远不会调用handleError()的子类覆盖。

open()进程永远不会达到这一点。如果我暂停调试器,我可以看到的是,在与打开过程相关的互斥/信号量上阻塞了几个线程: enter image description here enter image description here

第二个线程(11)似乎正在处理某种文件冲突,但我无法理解为什么以及为什么。当我在打开文件之前检查documentState时,我可以看到它的值为[.normal, .closed]

这是初始化文档的代码 - 非常直接,并且可以按预期用于大多数用途和用例:

class MyDataManager {

static var sharedInstance = MyDataManager()

var managedDoc : UIManagedDocument!
var docUrl : URL!

var managedObjContext : NSManagedObjectContext {
    return managedDoc.managedObjectContext
}

func configureCoreData(forUser: String, completion: @escaping (Bool)->Void) {

    let dir = UserProfile.profile.getDocumentsDirectory()
    docUrl = dir.appendingPathComponent(forUser + GlobalDataDocUrl, isDirectory: true)

    managedDoc = UIManagedDocument(fileURL: docUrl)

    //allow the UIManagedDoc to perform lieghtweight migration of the DB in case of small changes in the model
    managedDoc.persistentStoreOptions = [
        NSMigratePersistentStoresAutomaticallyOption: true,
        NSInferMappingModelAutomaticallyOption: true
    ]


    switch (self.managedDoc.documentState)
    {
    case UIDocumentState.normal:
        DDLogInfo("ManagedDocument is ready \(self.docUrl)")
    case UIDocumentState.closed:
        DDLogInfo("ManagedDocument is closed - will open it")
        if FileManager.default.fileExists(atPath: self.docUrl.path) {
            self.managedDoc.open() { [unowned self] (success) in
                DDLogInfo("ManagedDocument is open result=\(success)")
                completion(success)
            }
        }
        else{
            self.managedDoc.save(to: self.managedDoc.fileURL, for: .forCreating) { [unowned self]  (success) in
                DDLogInfo("ManagedDocument created result=\(success) ")
                completion(success)
            }

        }
    case UIDocumentState.editingDisabled:
        fallthrough
    case UIDocumentState.inConflict:
        fallthrough
    case UIDocumentState.progressAvailable:
        fallthrough
    case UIDocumentState.savingError:
        fallthrough
    default:
        DDLogWarn("ManagedDocument status is  \(self.managedDoc.documentState.rawValue)")
    }
}
}

再次 - managedDoc.open()的闭包回调永远不会被调用。好像文件处于某种不良状态,无法打开。 顺便说一句,如果我将app容器从设备复制到我的mac并打开SQLLite存储,我可以看到所有内容都按预期存在。

0 个答案:

没有答案