В чем разница с fetchRequest с objectID и существующим объектом (с :) - PullRequest
0 голосов
/ 21 апреля 2020

Я удаляю документ (NSManagedObject) в managedObjectContext. Тем временем фоновая задача завершает работу для этого документа и сохраняет его контекст. Я хочу иметь возможность проверить, был ли документ удален, и я не понимаю лучший способ go:

Согласно этот пост путь к go использовать existingObject(with: document.objectID).

Но когда я делаю это, он возвращает правильный объект.

print(try existingObject(with: document.objectID)) // prints the object

С другой стороны, если я пытаюсь получить объект следующим образом, то я получаю правильный результат (выводится 0):

let fetchRequest = Document.fetchRequest() as! NSFetchRequest<Document>
fetchRequest.fetchBatchSize = 1
fetchRequest.includesPendingChanges = false
fetchRequest.predicate = NSPredicate(format: "self = %@", object.objectID)
let results = try fetch(fetchRequest)
print(results.count)

Может кто-нибудь объяснить, почему existingObject(with:) не возвращает ноль? Из вышеупомянутого поста StackOverflow я понял, что так и должно быть. Но мне кажется, что он просто возвращает кэшированный объект из текущего контекста, если он существует, и не беспокоит go проверка в постоянном хранилище.

Я добавляю автономный пример, который показывает, что не совсем понятно:

import CoreData
import UIKit

private func checkExists(_ objectID: NSManagedObjectID, in context: NSManagedObjectContext) -> Bool {
    let fetchRequest: NSFetchRequest<NSManagedObject> = NSFetchRequest(entityName: "Document")
    fetchRequest.fetchBatchSize = 1
    fetchRequest.includesPendingChanges = false
    fetchRequest.predicate = NSPredicate(format: "self = %@", objectID)
    let results = try! context.fetch(fetchRequest)
    return results.count != 0
}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        let context = persistentContainer.viewContext


        let entity = NSEntityDescription.entity(forEntityName: "Document", in: context)!
        let document = NSManagedObject(entity: entity, insertInto: context)
        document.setValue("my document", forKey: "name")
        try! context.save()

        let context2 = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
        context2.parent = context

        context2.perform {
            assert((try? context2.existingObject(with: document.objectID)) != nil)

            context.performAndWait {
                context.delete(document)
                try! context.save()
            }

            assert(!checkExists(document.objectID, in: context)) // Success
            assert((try? context2.existingObject(with: document.objectID)) == nil) // Fails !
        }
    }

    lazy var persistentContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: "Test")
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        })
        return container
    }()
}

...