Сбой CoreData при извлечении данных в цикле - PullRequest
0 голосов
/ 27 июня 2018

Я работаю со старым xcdatamodel, он был создан в xcode 7.3 (это крайне важно, поскольку у меня нет следующей проблемы на современных моделях). В то же время, эта проблема не решается простым изменением Tool Version на Xcode 9.0 для моего xcdatamodel.

Я извлекаю данные в цикле for, в потоке контекста, который я использую для извлечения данных. Когда я пытаюсь получить объект, который уже был получен один раз, coreData вылетает с EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP). Отслеживание зомби говорит [CFString copy]: message sent to deallocated instance 0x608000676b40.

Это концепция того, что я делаю:

LegacyDatabaser.context.perform {
    do {
        for _ in 0..<10 {
            let entity = try self.legacyDatabase.getEntity(forId:1)
            print(entity.some_string_property) // <- crash here
        }
    } catch {
        // ...
    }
}

Вот инициализатор контекста:

class LegacyDatabaser {
     static var context: NSManagedObjectContext = LegacyDatabaseUtility.context
     // ...
}

И

class LegacyDatabaseUtility {
    fileprivate class var context: NSManagedObjectContext {
        //let context = NSManagedObjectContext(concurrencyType:.privateQueueConcurrencyType)
        //context.persistentStoreCoordinator = storeContainer.persistentStoreCoordinator
        //return context // This didn't help also
        return storeContainer.newBackgroundContext() 
    }
    private static var storeContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name:"MyDBName")
        container.loadPersistentStores { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        }
        return container
    }()
}

Вот сборщик данных:

func getEntity(forId id: NSNumber) throws -> MyEntity? {

    // Create predicate
    let predicate = NSPredicate(format:"id_local == %@", id)

    // Find items in db
    let results = try LegacyDatabaseUtility.find(predicate:predicate, sortDescriptors:nil, in:LegacyDatabaser.context)

    // Check it
    if results.count == 1 {
        if let result = results.first as? MyEntity {
            return result        
        } else {
            return nil
        }
    } else {
        return nil
    }
}

И

static func find(predicate:NSPredicate?, sortDescriptors:[NSSortDescriptor]?, in context: NSManagedObjectContext) throws -> [NSManagedObject] {

    // Create a request
    let fetchRequest = NSFetchRequest<NSManagedObject>(entityName:"MyEntity")

    // Apply predicate
    if let predicate = predicate {
        fetchRequest.predicate = predicate
    }

    // Apply sorting
    if let sortDescriptors = sortDescriptors {
        fetchRequest.sortDescriptors = sortDescriptors
    }

    // Run the fetchRequest
    return try context.fetch(fetchRequest)
}

Я не обращаюсь к контексту где-то параллельно, я уверен, что использую правильный поток и контекст (я также протестировал основной контекст, тот же результат). Что я делаю не так, почему повторное извлечение той же сущности не удается?

1 Ответ

0 голосов
/ 27 июня 2018

Если кто-либо обнаруживает какие-либо причудливые сбои, подобные описанным выше, проверьте свойства в вашем NSManagedObject. В моем случае сбои были при вызове свойства new_id, которое, я думаю, является зарезервированным именем. Как только я переименовал это свойство, сбои прекратились.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...