通过核心数据关系改变属性值
Change Value of Attribute Through Core Data Relationship
我正在努力更新存储在与另一个实体有 "one-to-many" 关系的实体中的值。
我的项目是一个预算应用程序。使用 NSFetchedResultsController,我可以成功地添加一个事务(填充在 table 中)并删除 FRC 自动保存的事务。
我有一个实体存储具有属性 "name" 和 "amount" 的交易,我有一个单独的实体具有一个属性 "theDate" (NSDate),用于存储日期交易。
之所以分开是因为我相信这会在组织上使它变得更简单——许多交易可以在同一天发生。
在下面我创建实体并在创建新事务后存储值,然后设置关系:
@IBAction func done(segue: UIStoryboardSegue) {
let addTransactionVC = segue.sourceViewController as! AddTransaction
let newTrans = addTransactionVC.newTransaction
let date = addTransactionVC.datePicker.date
// Create Entities
let entity = NSEntityDescription.entityForName("DailyTransactions", inManagedObjectContext: self.managedContext)
let relatedEntity = NSEntityDescription.entityForName("TransDates", inManagedObjectContext: self.managedContext)
// Initialize Record
let record = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: self.managedContext)
let recordDate = NSManagedObject(entity: relatedEntity!, insertIntoManagedObjectContext: self.managedContext)
// Is new transaction being created or an old one being edited?
if !addTransactionVC.isEditingTransaction {
// Populate Record
record.setValue(newTrans.name, forKey: "transName")
record.setValue(newTrans.amount, forKey: "transAmount")
recordDate.setValue(date, forKey: "theDate")
// Create Relationship of Date to Transaction
record.setValue(recordDate, forKey: "date")
} else {
// If user was editing a transaction:
let updatedObject = addTransactionVC.managedObject
let newDate = addTransactionVC.datePicker.date
// How do I change the date associated with this transaction?
updatedObject.setValue(newTrans.name, forKey: "transName")
updatedObject.setValue(newTrans.amount, forKey: "transAmount")
// This line was meant to access the attribute in the "date" relationship:
updatedObject.setValue(newDate, forKey: "date")
else
以上的一切工作正常。如果选择要编辑的单元格(事务),则在 else
之后触发。此行:updatedObject.setValue(newDate, forKey: "date")
旨在简单地更新 TransDates 实体的 "theDate" 属性("date" 是关系的名称)。但我现在明白为什么那行不通了。
所以我在 else 语句中尝试了这个:
let fetchRequestDates = NSFetchRequest(entityName: "TransDates")
do {
let dateObjects = try self.managedContext.executeFetchRequest(fetchRequestDates) as! [TransDates]
for dateObject in dateObjects {
// These 2 lines were to test that a date was being returned:
let tempDate = dateObject.theDate as! NSDate
print("dateObject is:\n\(String(tempDate))")
if dateObject.valueForKey("theDate") as! NSDate == newDate {
updatedObject.setValue(dateObject, forKey: "date")
break
}
}
} catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
我认为上面的内容只是 return 所有 TransDates 对象的数组,如果找到匹配项(b/w 数组中的内容和新的 NSDate),updatedObject 将被添加到它,否则我会添加一些代码来将 newDate 创建为新的 NSManagedObject 等。
但是在执行 if dateObject.valueForKey("theDate") as! NSDate == newDate {
时会发生这种情况:"fatal error: unexpectedly found nil while unwrapping an Optional value".
我的两个问题:
根据我正在尝试的 accomplish-update/change 与交易关联的日期(如果该日期已经存在并且包含其他交易,则该交易只是移动到加入它们), 这是最好的方法吗?
难道我的purpose/functionality感情都错了?
抱歉这个冗长的问题,但我已经被困在这里好几天了。提前致谢!
您收到此错误的原因是您试图强制解包一个 nil 值。您应该改为使用 if let
语句:
if let date dateObject.valueForKey("theDate") as? NSDate {
if date == newDate {
...
}
}
我正在努力更新存储在与另一个实体有 "one-to-many" 关系的实体中的值。
我的项目是一个预算应用程序。使用 NSFetchedResultsController,我可以成功地添加一个事务(填充在 table 中)并删除 FRC 自动保存的事务。
我有一个实体存储具有属性 "name" 和 "amount" 的交易,我有一个单独的实体具有一个属性 "theDate" (NSDate),用于存储日期交易。
之所以分开是因为我相信这会在组织上使它变得更简单——许多交易可以在同一天发生。
在下面我创建实体并在创建新事务后存储值,然后设置关系:
@IBAction func done(segue: UIStoryboardSegue) {
let addTransactionVC = segue.sourceViewController as! AddTransaction
let newTrans = addTransactionVC.newTransaction
let date = addTransactionVC.datePicker.date
// Create Entities
let entity = NSEntityDescription.entityForName("DailyTransactions", inManagedObjectContext: self.managedContext)
let relatedEntity = NSEntityDescription.entityForName("TransDates", inManagedObjectContext: self.managedContext)
// Initialize Record
let record = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: self.managedContext)
let recordDate = NSManagedObject(entity: relatedEntity!, insertIntoManagedObjectContext: self.managedContext)
// Is new transaction being created or an old one being edited?
if !addTransactionVC.isEditingTransaction {
// Populate Record
record.setValue(newTrans.name, forKey: "transName")
record.setValue(newTrans.amount, forKey: "transAmount")
recordDate.setValue(date, forKey: "theDate")
// Create Relationship of Date to Transaction
record.setValue(recordDate, forKey: "date")
} else {
// If user was editing a transaction:
let updatedObject = addTransactionVC.managedObject
let newDate = addTransactionVC.datePicker.date
// How do I change the date associated with this transaction?
updatedObject.setValue(newTrans.name, forKey: "transName")
updatedObject.setValue(newTrans.amount, forKey: "transAmount")
// This line was meant to access the attribute in the "date" relationship:
updatedObject.setValue(newDate, forKey: "date")
else
以上的一切工作正常。如果选择要编辑的单元格(事务),则在 else
之后触发。此行:updatedObject.setValue(newDate, forKey: "date")
旨在简单地更新 TransDates 实体的 "theDate" 属性("date" 是关系的名称)。但我现在明白为什么那行不通了。
所以我在 else 语句中尝试了这个:
let fetchRequestDates = NSFetchRequest(entityName: "TransDates")
do {
let dateObjects = try self.managedContext.executeFetchRequest(fetchRequestDates) as! [TransDates]
for dateObject in dateObjects {
// These 2 lines were to test that a date was being returned:
let tempDate = dateObject.theDate as! NSDate
print("dateObject is:\n\(String(tempDate))")
if dateObject.valueForKey("theDate") as! NSDate == newDate {
updatedObject.setValue(dateObject, forKey: "date")
break
}
}
} catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
我认为上面的内容只是 return 所有 TransDates 对象的数组,如果找到匹配项(b/w 数组中的内容和新的 NSDate),updatedObject 将被添加到它,否则我会添加一些代码来将 newDate 创建为新的 NSManagedObject 等。
但是在执行 if dateObject.valueForKey("theDate") as! NSDate == newDate {
时会发生这种情况:"fatal error: unexpectedly found nil while unwrapping an Optional value".
我的两个问题:
根据我正在尝试的 accomplish-update/change 与交易关联的日期(如果该日期已经存在并且包含其他交易,则该交易只是移动到加入它们), 这是最好的方法吗?
难道我的purpose/functionality感情都错了?
抱歉这个冗长的问题,但我已经被困在这里好几天了。提前致谢!
您收到此错误的原因是您试图强制解包一个 nil 值。您应该改为使用 if let
语句:
if let date dateObject.valueForKey("theDate") as? NSDate {
if date == newDate {
...
}
}