NSPersistentStoreCoordinator.migratePersistentStore-我可以加快速度吗?

时间:2019-06-16 10:25:12

标签: ios swift core-data

在我的项目中,我需要创建数据库备份的可能性,因此根据此blog,我创建了NSPersistentStoreCoordinator扩展名:

import Foundation
import CoreData

extension NSPersistentStoreCoordinator {

    /// Safely copies the specified `NSPersistentStore` to a file.
    ///
    /// Credits: https://oleb.net/blog/2018/03/core-data-sqlite-backup/
    func backupPersistentStore(atIndex index: Int) throws {
        // Inspiration: https://stackoverflow.com/a/22672386
        // Documentation for NSPersistentStoreCoordinate.migratePersistentStore:
        // "After invocation of this method, the specified [source] store is
        // removed from the coordinator and thus no longer a useful reference."
        // => Strategy:
        // 1. Create a new "intermediate" NSPersistentStoreCoordinator and add
        //    the original store file.
        // 2. Use this new PSC to migrate to a new file URL.
        // 3. Drop all reference to the intermediate PSC.
        let sourceStore = persistentStores[index]
        let backupCoordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel)

        let intermediateStoreOptions = (sourceStore.options ?? [:]).merging(
            [NSReadOnlyPersistentStoreOption: true],
            uniquingKeysWith: { $1 }
        )
        let intermediateStore = try backupCoordinator.addPersistentStore(
            ofType: sourceStore.type,
            configurationName: sourceStore.configurationName,
            at: sourceStore.url,
            options: intermediateStoreOptions
        )

        let backupStoreOptions: [AnyHashable: Any] = [
            NSReadOnlyPersistentStoreOption: true,
            // Disable write-ahead logging. Benefit: the entire store will be
            // contained in a single file. No need to handle -wal/-shm files.
            // https://developer.apple.com/library/content/qa/qa1809/_index.html
            NSSQLitePragmasOption: ["journal_mode": "DELETE"],
            // Minimize file size
            NSSQLiteManualVacuumOption: true,
        ]
        let backupUrl = try prepareBackupUrl()

        try backupCoordinator.migratePersistentStore(
            intermediateStore,
            to: backupUrl,
            options: backupStoreOptions,
            withType: NSSQLiteStoreType
        )
    }

    /// Remeber to reload persistent stores if you using `NSPersistentContainer`
    /// `NSPersistentContainer.loadPersistentStores`
    func restorePersistentStore(atIndex index: Int) throws {
        let sourceStore = persistentStores[index]
        let sourceStoreUrl = sourceStore.url!
        let backupUrl = backupFileUrl()

        try replacePersistentStore(
            at: sourceStoreUrl,
            destinationOptions: nil,
            withPersistentStoreFrom: backupUrl,
            sourceOptions: nil,
            ofType: NSSQLiteStoreType
        )
    }
}

不幸的是,当数据库很大时,migratePersistentStore的执行时间很长。我正在寻找一些改进措施以加快这一过程。

我对NSPersistentContainer.migratePersistentStore选项不熟悉。经过一天的研究,我决定在这里寻求帮助。

也许不需要NSSQLiteManualVacuumOption。也许其他选择对我有帮助。

我的目标:加快migratePersistentStore。可以使用replacePersistentStore从创建的备份中还原Core Date。

谢谢您的任何建议。

0 个答案:

没有答案