swift - saveContext() 的工作差异取决于 viewController 的实例化。CoreData Enigma
问题描述
该项目有一个简约的 CoreData 堆栈。
我有一个 UIViewController 子类“AddOrChangeEntityVC”来创建 NSManagedObject,更改其属性并将数据写入 DB。
如果“AddOrChangeEntityViewController”是从 MyFirstVC、MySecondVC、...和 MyNinthVC 创建的,则列出的函数可以正常工作,任何其他视图控制器都可以使用 BadVC。在这种情况下,尝试将实体写入数据库,所有属性 = nil。
我看到了这个错误。
Error Domain=NSCocoaErrorDomain Code=1560 "Multiple validation errors occurred."
对于每个必需的属性,例如
"Error Domain=NSCocoaErrorDomain Code=1570 \"firstProperty is a required value.\
UserInfo={NSValidationErrorObject=<APP.Entity: 0x600006917e80> (entity: Entity; id: 0x600000f152a0 <x-coredata:///Entity/t72AEC6D7-A854-40A3-BA9D-5830DFADC8AF2>; data: {\n firstProperty = nil;\n secondProperty = nil;\n}), NSValidationErrorKey = firstValue, NSLocalizedDescription=firstValue is a required value"
"Error Domain=NSCocoaErrorDomain Code=1570 \"secondProperty is a required value.\"
应该注意的是,在 saveContext() 调用之前,所有属性都经过验证。
AddOrChangeEntityVC: UIViewController {
var entity: Entity?
func saveEntity() -> Bool {
//validating data
if !validateData() {
return false
}
//creating passenger
if entity == nil {
entity = Entity()
}
//saving entity
if let entity = entity {
//saving
entity.firstProperty = firstPropertyTextfield.text!
entity.secondProperty = secondPropertyTextfield.text!
...
CoreDataStack.shared.saveContext()
return true
}
}
Entity: NSManaged
class Entity: NSManagedObject {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Entity> {
return NSFetchRequest<Entity>(entityName: "Entity")
}
@NSManaged public var firstProperty: String
@NSManaged public var secondProperty: String
convenience init() {
let entity = NSEntityDescription.entity(forEntityName: "Entity",
in: CoreDataStack.shared.persistentContainer.viewContext)!
self.init(entity: entity, insertInto: CoreDataStack.shared.persistentContainer.viewContext)
}
}
核心数据管理器
class CoreDataStack {
static var shared = CoreDataStack()
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "APP")
container.loadPersistentStores { storeDesription, error in
guard error == nil else {
fatalError("Unresolved error \(error!)")
}
}
// Merge the changes from other contexts automatically. useв for Another Entity
enter code here
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
container.viewContext.shouldDeleteInaccessibleFaults = true
return container
}()
func saveContext() {
let context = persistentContainer.viewContext
guard context.hasChanges else { return }
do {
try context.save()
} catch let error as NSError{
print("Error: \(error), \(error.userInfo)")
}
}
}
从 anyVC 转换到 AddOrChangeEntityVC
guard let entityVC = self.storyboard?.instantiateViewController(withIdentifier: "addEntityVC") as? AddOrChangeEntityVC else {return}
self.navigationController?.pushViewController(entityVC, animated: true)
```
解决方案
好吧,Core Data 是神秘的,甚至是晦涩难懂的。
我做了这个简单的步骤。1)在 AddOrChangeEntityVC 我添加
var context: NSManagedObjectContext = CoreDataStack.shared.persistentContainer.newBackGroundContext()
2)在Entity的初始化中:NSManaged(如果我们需要创建它)
if entity == nil {
entity = Entity(context: context)
}
3) 出乎意料地面对,在 NSFetchingResultController 结果中添加了一些新的神秘实体后,所有属性 == nil 我在 tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 方法和 tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 通过从 fetchedResultsController.fetchedObjects 中删除?具有某些属性的元素 == nil。
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return fetchedResultsController.fetchedObjects?.filter({!$0.firstProperty.isEmpty}).count ?? 0
}
和
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if fetchedResultsController.object(at: indexPath).isValid {
let entity = fetchedResultsController.object(at: indexPath)
let cell = UITableViewCell()update(with: entity)
....
}
推荐阅读
- javascript - 错误阻止加载 Jquery.js - 内容安全策略
- bash - Calling function from another function in Bash
- date - Using SELECT IF to recode one date from four variables in SPSS
- c# - 使用 C# 在线列出 Sharepoint 上文件夹中的所有文件
- r - 有没有办法在 Rstudio ggplot 中订购堆积条形图,以便根据子集的增加或减少对条形图进行排序?
- r - 如何使用多个中介进行多层次中介分析?
- python-3.x - 获取 XML 中字段的值
- javascript - 如何在 For 循环中从 Web 打印图像
- graphdb - GraphDB 自定义规则集编译失败:代码太大
- javascript - videoJS: mouseTimeDisplay $(selector, contextopt) 方法示例