我的核心数据出现了连线问题。使用iOS 10中的Swift3,我每次获取或存储数据时都会获得托管对象上下文
func getContext () -> NSManagedObjectContext {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
return appDelegate.persistentContainer.viewContext
}在我的应用中,我有两个实体'User‘和'Ledger’。我想将一个账本分配给一个用户,但一个用户可以有多个账本。因此,我有一个可以显示users的UserTableView和一个可以创建user的UserViewController类。我对账本也是一样。创建账本时,我还会得到一个所有用户的列表,从中选择一个用户,并将哪些用户分配给账本,反之亦然。
当像上面提到的那样保存时,我得到了错误
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unacceptable type of value for to-one relationship: property = "user"; desired type = User; given type = User;我的数据模型如下所示:Data Model
我们非常感谢您的帮助:)
发布于 2017-07-27 22:06:45
我也有同样的问题。在我的例子中,它是在我运行单元测试时发生的。在这种情况下,内存中同时有两个核心数据堆栈,一个用于应用程序控制,另一个用于我正在运行的单元测试。
解决这个问题的第一个线索是在设置relationship属性之前设置一个断言,以确保我正在设置的对象的实体类型与关系的预期实体类型相同。它们应该是相同的,但在我的例子中却不是。
在我的例子中,我有一个与Player具有一对一关系的MatchRequest,称为"initiator“。因此,我的断言如下所示:
let player = try Player.findLocal(for: matchRequest.initiator, in: moc, createIfMissing: true)
let expectedEntity = self.entity.relationshipsByName["initiator"]!.destinationEntity!
assert(player!.entity === expectedEntity, "Player returned doesn't have the same entity type")
self.initiator = player上面的断言失败了,我怀疑这与Core Data使用的导致参数异常的断言相似。
在检查Player.entity()时,它将返回导致失败的同一实体实例。
我认为问题的根源是核心数据正在为实体设置一些静态属性,这些属性将在核心数据堆栈之间不正确地共享。当从一个堆栈调用时,调用MyManagedObject.entity()将正常工作,而从另一个堆栈调用则不会。
因此,为了解决这个问题,当我创建要放入关系中的播放器对象时,我使用较旧的NSEntityDescription.insertNewObject(...) API而不是较新的MyManagedObject(context:)构造函数来获取实体。这可确保为给定的托管对象上下文使用正确的实体。
所以,重述一下:
// SOMETIMES FAILS if you have more than one core data stack:
result = Player(context: managedObjectContext)
// ALWAYS WORKS:
result = NSEntityDescription.insertNewObject(forEntityName: "Player", into: managedObjectContext) as? Player发布于 2019-01-29 21:17:36
我也有同样的问题,但我非常确定我没有像上一个答案那样有2个核心数据堆栈。
最后,我意识到我已经使用lazy关键字初始化了对NSStoreCoordinator的引用、视图上下文和背景上下文。我也有一堆代码在后台线程中做一些繁重的提升,并使用所述堆栈进行保存。
苹果公司的文档说:“如果一个标有惰性修饰符的属性被多个线程同时访问,并且该属性还没有被初始化,就不能保证该属性只被初始化一次。”
所以,这个不幸的场景是导致这个错误的另一种方式。解决方案:确保在核心数据堆栈中不要lazy任何东西,特别是在执行大量后台/前台线程工作时。
我希望它能在未来帮助一些人。如果你在这里,对你未来的开发者说:祝你好运。
发布于 2020-12-04 09:42:33
我也遇到了同样的问题。我认为@Chris已经清楚地给出了原因。进行测试时,内存中有多个实例。
解决方案是将NSPersistentContainer初始化部分移到setUpWithError和tearDownWithError中。
在下面的示例中,CoreDataManager负责NSPersistentContainer的init。
代码如下:
之前的
class FooTests: XCTestCase {
var manager: CoreDataManager = CoreDataManager()
}之后的
class FooTests: XCTestCase {
var manager: CoreDataManager?
override func setUpWithError() throws {
manager = CoreDataManager(inMemory: true)
}
override func tearDownWithError() throws {
manager = nil
}
}https://stackoverflow.com/questions/40597981
复制相似问题