【发布时间】:2018-12-06 17:23:47
【问题描述】:
我正在使用旧的 xcdatamodel,它是在 xcode 7.3 中创建的(这是至关重要的,因为我在现代模型上没有以下问题)。同时,对于我的xcdatamodel,简单地将Tool Version 更改为Xcode 9.0 也无法解决此问题。
我在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)
}
我没有在某个地方并行处理上下文,我确定我使用了正确的线程和上下文(我也测试了主上下文,结果相同)。我做错了什么,为什么重新获取同一个实体会失败?
【问题讨论】:
-
不相关,但考虑在
getEntity()方法中成功返回non-optional 和throw在any 失败时返回错误。并且results.count == 1检查是多余的,如果数组为空,first返回nil。
标签: ios iphone swift core-data