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