Search code examples
iosswiftcore-data

How can we decide to choose `NSBatchUpdateRequest` or `NSManagedObject`, when updating 1 row?


I know that when updating multiple rows of data, NSBatchUpdateRequest is a recommended way, as it is faster and consumed less memory.

However, what if we are only updating 1 row? Should we choose to update using NSBatchUpdateRequest or NSManagedObject? Is there any rule-of-thumb to decide the choice?

Using NSManagedObject

func updateName(_ objectID: NSManagedObjectID, _ name: String) {
    let coreDataStack = CoreDataStack.INSTANCE
    let backgroundContext = coreDataStack.backgroundContext

    backgroundContext.perform {
        do {
            let nsTabInfo = try backgroundContext.existingObject(with: objectID) as! NSTabInfo 
            nsTabInfo.name = name
            RepositoryUtils.saveContextIfPossible(backgroundContext)
        } catch {
            backgroundContext.rollback()
            
            error_log(error)
        }
    }
}

Using NSBatchUpdateRequest

func updateName(_ objectID: NSManagedObjectID, _ name: String) {
    let coreDataStack = CoreDataStack.INSTANCE
    let backgroundContext = coreDataStack.backgroundContext

    backgroundContext.perform {
        do {
            let batchUpdateRequest = NSBatchUpdateRequest(entityName: "NSTabInfo")
            batchUpdateRequest.predicate = NSPredicate(format: "self == %@", objectID)
            batchUpdateRequest.propertiesToUpdate = ["name": name]
            batchUpdateRequest.resultType = .updatedObjectIDsResultType

            let batchUpdateResult = try backgroundContext.execute(batchUpdateRequest) as? NSBatchUpdateResult

            guard let batchUpdateResult = batchUpdateResult else { return }
            guard let managedObjectIDs = batchUpdateResult.result else { return }

            let changes = [NSUpdatedObjectsKey : managedObjectIDs]
            coreDataStack.mergeChanges(changes)
        } catch {
            backgroundContext.rollback()

            error_log(error)
        }
    }
}

May I know how can we decide to choose NSBatchUpdateRequest or NSManagedObject, when updating 1 row?


Solution

  • For one/few objects (that can be easily pulled into memory without issues), it is usually easier/recommended to -

    1. fetch NSManagedObject into NSManagedObjectContext.
    2. Perform your updates.
    3. Save the context.

    This saves you from having to merge the same set of changes to all other contexts in the app (which may have reference to the object being updated).

    This works because NSManagedObjectContext fires notifications on save() calls that can be automatically observed by other contexts (if needed).