iOS9 Xcode 7 - 核心数据 - 避免重复对象
iOS9 Xcode 7 - Core Data - avoiding duplicated objects
如 WWDC2015 presentation video 中所述,在新的 Xcode7 中,我们可以直接在 Xcode 模型编辑器中设置对象的唯一性。我试图实现我的代码,但有些东西没有按预期工作。
当我尝试保存重复的对象时,Xcode 拒绝保存,但 table 更新了重复的单元格。
所以我设置了独特的属性开始日期和结束日期。
然后我修改了我的保存函数来处理错误并通过 UIAlertController 通知用户。
func addContract() {
do {
let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context: NSManagedObjectContext = appDelegate.managedObjectContext
let entity = NSEntityDescription.entityForName("Contract", inManagedObjectContext: context)
let newContractData = Contract(entity: entity!, insertIntoManagedObjectContext: context)
newContractData.startdate = dateFormatter.dateFromString(startDateTextField.text!)!
newContractData.enddate = dateFormatter.dateFromString(endDateTextField.text!)!
newContractData.ship = shipNameTextField.text!
newContractData.position = positionOnBoardTextField.text!
newContractData.workingdays = Int(workingDaysLabel.text!)!
try context.save()
} catch {
let alertController = UIAlertController(
title: "Error",
message: "The contract exsist",
preferredStyle: UIAlertControllerStyle.Alert)
let okAction = UIAlertAction(
title: "OK",
style: UIAlertActionStyle.Cancel,
handler: nil)
alertController.addAction(okAction)
presentViewController(alertController, animated: true, completion: nil)
}
}
到目前为止一切顺利,但是当我使用取消按钮返回到根控制器时,table 似乎更新了重复的单元格。
@IBAction func cancelButtonPressed(sender: UIBarButtonItem) {
self.navigationController?.popToRootViewControllerAnimated(true)
}
此外,停止并运行应用程序删除重复项。
这是一个 video 有问题的行为。
产生的错误如下:
Error Domain=NSCocoaErrorDomain Code=1551 "The operation couldn’t be completed. (Cocoa error 1551.)" UserInfo=0x7fc02d462190 {Conflicts=(
{
constraint = (
startdate,
enddate
);
entity = Contract;
objects = (
"<Contract: 0x7fc02d45ba60> (entity: Contract; id: 0x7fc02d019430 <x-coredata:///Contract/t0897571B-200B-4F04-AF87-D50831E2DE672> ; data: {\n enddate = \"2017-06-13 21:00:00 +0000\";\n position = test;\n ship = test;\n startdate = \"2016-06-13 21:00:00 +0000\";\n workingdays = 366;\n})",
"<Contract: 0x7fc02b7433c0> (entity: Contract; id: 0xd000000000100000 <x-coredata://C3318932-BEDB-4AB6-A856-103F542BCF44/Contract/p4> ; data: {\n enddate = \"2017-06-13 21:00:00 +0000\";\n position = test;\n ship = test;\n startdate = \"2016-06-13 21:00:00 +0000\";\n workingdays = 366;\n})"
);
}
)}
2015-06-14 19:54:15.880 WorkingDays[6028:2219449] popToViewController:transition: called on <UINavigationController 0x7fc02c007e00> while an existing transition or presentation is occurring; the navigation stack will not be updated.
修正addContract()方法如下:
func addContract() {
let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context: NSManagedObjectContext = appDelegate.managedObjectContext
let entity = NSEntityDescription.entityForName("Contract", inManagedObjectContext: context)
let newContractData = Contract(entity: entity!, insertIntoManagedObjectContext: context)
do {
newContractData.startdate = dateFormatter.dateFromString(startDateTextField.text!)!
newContractData.enddate = dateFormatter.dateFromString(endDateTextField.text!)!
newContractData.ship = shipNameTextField.text!
newContractData.position = positionOnBoardTextField.text!
newContractData.workingdays = Int(workingDaysLabel.text!)!
try context.save()
} catch {
let alertController = UIAlertController(
title: "Error",
message: "The contract exsist",
preferredStyle: UIAlertControllerStyle.Alert)
let okAction = UIAlertAction(
title: "OK",
style: UIAlertActionStyle.Cancel,
handler: nil)
alertController.addAction(okAction)
presentViewController(alertController, animated: true, completion: nil)
context.deleteObject(newContractData)
print(error)
}
}
您是否使用 NSFetchedResultsController
来显示数据?
看来只有保存才能保证唯一性。
但是 Core Data 仍然允许您在执行以下操作时将对象插入 NSManagedObjectContext
:
let newContractData = Contract(entity: entity!, insertIntoManagedObjectContext: context)
当您保存时,保存操作失败,但该对象仍在上下文中,因此 NSFetchedResultsController
仍然显示它。
尝试从捕获代码的上下文中删除对象:
context.deleteObject(newContractData)
如 WWDC2015 presentation video 中所述,在新的 Xcode7 中,我们可以直接在 Xcode 模型编辑器中设置对象的唯一性。我试图实现我的代码,但有些东西没有按预期工作。 当我尝试保存重复的对象时,Xcode 拒绝保存,但 table 更新了重复的单元格。
所以我设置了独特的属性开始日期和结束日期。
然后我修改了我的保存函数来处理错误并通过 UIAlertController 通知用户。
func addContract() {
do {
let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context: NSManagedObjectContext = appDelegate.managedObjectContext
let entity = NSEntityDescription.entityForName("Contract", inManagedObjectContext: context)
let newContractData = Contract(entity: entity!, insertIntoManagedObjectContext: context)
newContractData.startdate = dateFormatter.dateFromString(startDateTextField.text!)!
newContractData.enddate = dateFormatter.dateFromString(endDateTextField.text!)!
newContractData.ship = shipNameTextField.text!
newContractData.position = positionOnBoardTextField.text!
newContractData.workingdays = Int(workingDaysLabel.text!)!
try context.save()
} catch {
let alertController = UIAlertController(
title: "Error",
message: "The contract exsist",
preferredStyle: UIAlertControllerStyle.Alert)
let okAction = UIAlertAction(
title: "OK",
style: UIAlertActionStyle.Cancel,
handler: nil)
alertController.addAction(okAction)
presentViewController(alertController, animated: true, completion: nil)
}
}
到目前为止一切顺利,但是当我使用取消按钮返回到根控制器时,table 似乎更新了重复的单元格。
@IBAction func cancelButtonPressed(sender: UIBarButtonItem) {
self.navigationController?.popToRootViewControllerAnimated(true)
}
此外,停止并运行应用程序删除重复项。
这是一个 video 有问题的行为。
产生的错误如下:
Error Domain=NSCocoaErrorDomain Code=1551 "The operation couldn’t be completed. (Cocoa error 1551.)" UserInfo=0x7fc02d462190 {Conflicts=(
{
constraint = (
startdate,
enddate
);
entity = Contract;
objects = (
"<Contract: 0x7fc02d45ba60> (entity: Contract; id: 0x7fc02d019430 <x-coredata:///Contract/t0897571B-200B-4F04-AF87-D50831E2DE672> ; data: {\n enddate = \"2017-06-13 21:00:00 +0000\";\n position = test;\n ship = test;\n startdate = \"2016-06-13 21:00:00 +0000\";\n workingdays = 366;\n})",
"<Contract: 0x7fc02b7433c0> (entity: Contract; id: 0xd000000000100000 <x-coredata://C3318932-BEDB-4AB6-A856-103F542BCF44/Contract/p4> ; data: {\n enddate = \"2017-06-13 21:00:00 +0000\";\n position = test;\n ship = test;\n startdate = \"2016-06-13 21:00:00 +0000\";\n workingdays = 366;\n})"
);
}
)}
2015-06-14 19:54:15.880 WorkingDays[6028:2219449] popToViewController:transition: called on <UINavigationController 0x7fc02c007e00> while an existing transition or presentation is occurring; the navigation stack will not be updated.
修正addContract()方法如下:
func addContract() {
let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context: NSManagedObjectContext = appDelegate.managedObjectContext
let entity = NSEntityDescription.entityForName("Contract", inManagedObjectContext: context)
let newContractData = Contract(entity: entity!, insertIntoManagedObjectContext: context)
do {
newContractData.startdate = dateFormatter.dateFromString(startDateTextField.text!)!
newContractData.enddate = dateFormatter.dateFromString(endDateTextField.text!)!
newContractData.ship = shipNameTextField.text!
newContractData.position = positionOnBoardTextField.text!
newContractData.workingdays = Int(workingDaysLabel.text!)!
try context.save()
} catch {
let alertController = UIAlertController(
title: "Error",
message: "The contract exsist",
preferredStyle: UIAlertControllerStyle.Alert)
let okAction = UIAlertAction(
title: "OK",
style: UIAlertActionStyle.Cancel,
handler: nil)
alertController.addAction(okAction)
presentViewController(alertController, animated: true, completion: nil)
context.deleteObject(newContractData)
print(error)
}
}
您是否使用 NSFetchedResultsController
来显示数据?
看来只有保存才能保证唯一性。
但是 Core Data 仍然允许您在执行以下操作时将对象插入 NSManagedObjectContext
:
let newContractData = Contract(entity: entity!, insertIntoManagedObjectContext: context)
当您保存时,保存操作失败,但该对象仍在上下文中,因此 NSFetchedResultsController
仍然显示它。
尝试从捕获代码的上下文中删除对象:
context.deleteObject(newContractData)