繁体   English   中英

在 NSPersistentStoreCoordinator 上调用 destroyPersistentStore 后,我应该删除底层持久存储文件吗?

[英]Should I delete underlying persistent store files after calling destroyPersistentStore on a NSPersistentStoreCoordinator?

我正在迁移我的 iOS 应用程序以使用NSPersistentContainer 默认情况下,此类将其持久存储文件定位在Library/Application Support目录中; 以前我的商店文件存储在Documents目录中。

如果在旧目录中找到存储文件,我添加了一些代码来移动存储文件:

func moveStoreFromLegacyLocationIfNecessary(toNewLocation newLocation: URL) {

    // The old store location is in the Documents directory
    let legacyStoreLocation = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("books.sqlite")

    // Check whether the old store exists and the new one does not
    if FileManager.default.fileExists(atPath: legacyStoreLocation.path) && !FileManager.default.fileExists(atPath: newLocation.path) {

        print("Store located in Documents directory; migrating to Application Support directory")
        let tempStoreCoordinator = NSPersistentStoreCoordinator()
        try! tempStoreCoordinator.replacePersistentStore(at: newLocation, destinationOptions: nil, withPersistentStoreFrom: legacyStoreLocation, sourceOptions: nil, ofType: NSSQLiteStoreType)

        // Delete the old store
        try? tempStoreCoordinator.destroyPersistentStore(at: legacyStoreLocation, ofType: NSSQLiteStoreType, options: nil)
    }
}

在调用destroyPersistentStore(at: url)之后,存储文件仍然存在于磁盘上。 这些会在某个时候自动清理吗? 还是我应该删除它们? 我还应该删除.sqlite-shm.sqlite-wal文件吗?

NSPersistentStoreCoordinator.destroyPersistentStore(at:type:options:)的文档指出:

在提供的位置删除特定类型的持久存储。

在与 WWDC 实验室的工程师交谈时,他们解释说它实际上并没有像文档所暗示的那样删除所提供位置的数据库文件。 它实际上只是截断而不是删除。 如果您希望它们消失,您可以手动删除文件(如果您可以确保没有其他进程或不同的线程正在访问它们)。

这是我在我的应用程序中实现的:

try coordinator.replacePersistentStore(at: sharedStoreURL, destinationOptions: nil, withPersistentStoreFrom: defaultStoreURL, sourceOptions: nil, ofType: NSSQLiteStoreType)
try coordinator.destroyPersistentStore(at: defaultStoreURL, ofType: NSSQLiteStoreType, options: nil)

// destroyPersistentStore says it deletes the old store but it actually truncates so we'll manually delete the files
NSFileCoordinator(filePresenter: nil).coordinate(writingItemAt: defaultStoreURL.deletingLastPathComponent(), options: .forDeleting, error: nil, byAccessor: { url in
    try? FileManager.default.removeItem(at: defaultStoreURL)
    try? FileManager.default.removeItem(at: defaultStoreURL.deletingLastPathComponent().appendingPathComponent("\(container.name).sqlite-shm"))
    try? FileManager.default.removeItem(at: defaultStoreURL.deletingLastPathComponent().appendingPathComponent("\(container.name).sqlite-wal"))
    try? FileManager.default.removeItem(at: defaultStoreURL.deletingLastPathComponent().appendingPathComponent("ckAssetFiles"))
})

我提交了 FB10181832 以请求更新文档以更好地解释其行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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