我正在努力学习CoreData
,其中一部分是弄清楚如何处理一对多的关系。对于练习,我正在编写一个包含人员列表的简单应用程序。每个人都可以有很多书。
这些是我的实体
extension Person {
@NSManaged var firstName: String?
@NSManaged var lastName: String?
@NSManaged var age: NSNumber?
@NSManaged var personToBook: NSSet?
}
extension Books {
@NSManaged var bookName: String?
@NSManaged var bookISBN: String?
@NSManaged var bookToPerson: Person?
}
该应用有两个列表,一个用于人,一个用于书籍。我有一个segue设置,所以当我选择一个人时,它会进入书籍列表,并显示书籍列表。书籍从书籍列表中添加。我在人员列表中设置了prepareForSegue
功能,以便将信息传递到图书清单。
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let vc = segue.destinationViewController as! BooksController
vc.person = fetchedResultsController.objectAtIndexPath(selectedIndex) as! Person
vc.context = self.context
vc.fetchedResultsController = self.fetchedResultsController
}
在图书清单上,有一个添加按钮,显示收集有关图书数据的UIAlertViewController
。
@IBAction func addItem(sender: UIBarButtonItem) {
let alertController = UIAlertController(title: "Add Person", message: "Enter data to add a new book" , preferredStyle: .Alert)
alertController.addTextFieldWithConfigurationHandler { (textField) in
textField.placeholder = "Book Name"
textField.keyboardType = .ASCIICapable
}
alertController.addTextFieldWithConfigurationHandler { (textField) in
textField.placeholder = "ISBN"
textField.keyboardType = .ASCIICapable
}
alertController.addAction(UIAlertAction(title: "Ok", style: .Default, handler: {
alert -> Void in
let entity = NSEntityDescription.entityForName("Books", inManagedObjectContext: self.context)
let bookInstance = Books(entity:entity!, insertIntoManagedObjectContext: self.context)
bookInstance.bookName = alertController.textFields?[0].text
bookInstance.bookISBN = alertController.textFields?[1].text
self.person.mutableSetValueForKey("personToBook").addObject(bookInstance)
do {
try self.context.save()
}
catch let error as NSError {
print("Error saving a book \(error.localizedDescription)")
}
}))
alertController.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
presentViewController(alertController, animated: true, completion: nil)
}
一切都适合添加人员。我可以毫无问题地添加,编辑和删除。我似乎能够以上述方式添加书籍,但是当UITableView
试图显示新添加的书籍时,我收到错误。错误是:
2015-11-28 16:43:41.911 OneToMany [52183:2082686] _BSMachError:(os / kern)无效功能(20) 2015-11-28 16:43:41.912 OneToMany [52183:2083078] _BSMachError:(os / kern)无效名称(15)
当我退出人员列表然后再回来时,刚添加的书就在列表中。在退出并返回列表之前,添加的书籍不会显示在书籍UITableView
上。
我不确定这段代码出错的地方。有什么建议吗?
答案 0 :(得分:1)
这个问题与CoreData没有任何关系,它与我在UIAlertAction
关闭内添加书籍有关。我更新了我的代码:
alertController.addAction(UIAlertAction(title: "Ok", style: .Default, handler: {
alert -> Void in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let entity = NSEntityDescription.entityForName("Books", inManagedObjectContext: self.context)
let bookInstance = Books(entity:entity!, insertIntoManagedObjectContext: self.context)
bookInstance.bookName = alertController.textFields?[0].text
bookInstance.bookISBN = alertController.textFields?[1].text
self.person.mutableSetValueForKey("personToBook").addObject(bookInstance)
do {
try self.context.save()
self.tableView.reloadData()
}
catch let error as NSError {
print("Error saving a book \(error.localizedDescription)")
}
})
}))
此后,错误消失,tableView重新加载。
我在进一步搜索stackoverflow时发现错误。
我仍然不能100%确定这是处理CoreData中一对多关系的正确方法,但它似乎确实有效。