【问题标题】:CoreData crashes when fetching data in loopCoreData 在循环中获取数据时崩溃
【发布时间】: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-optionalthrowany 失败时返回错误。并且results.count == 1 检查是多余的,如果数组为空,first 返回nil

标签: ios iphone swift core-data


【解决方案1】:

如果有人发现我上面描述的任何怪癖崩溃,请检查您的NSManagedObject 中的属性名称。在我的情况下,崩溃是在调用new_id 属性,我猜,有点保留名称。一旦我重命名了这个属性,崩溃就停止了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-03
    • 1970-01-01
    相关资源
    最近更新 更多