情况
- 用户点击按钮将项目添加到 TableView 。
- TableView Controller 将项目和 segues 直接添加到编辑/详细 View Controller 。
项目是用 NSFetchedResultsController
填充的核心数据对象。
问题
如何获得对新对象的有效引用以便执行转场?我正在寻找通用模式,而不是违反任何 Core Data 规则。
代码
class MasterViewController: UITableViewController, NSFetchedResultsControllerDelegate {
var context: NSManagedObjectContext!
var frc: NSFetchedResultsController! // set up fetch request etc.
// User initiated
func addItem(_ sender: Any) {
context.perform {
let item = Item(context: context)
try! context.save()
}
// How to get hold of the new item and where to initiate the segue?
}
func prepare(for segue: UIStoryboardSegue, sender: Any) {
// Pass new item to detail view controller
}
// NSFetchedResultsControllerDelegate methods
// refresh table on updates
}
想法
1) 假设 context
是主视图上下文是否安全正确?
var newItem: Item?
func addItem(_ sender: Any) {
context.perform {
newItem = Item(context: context)
try! context.save() // error handling etc.
performSegue(...)
}
}
func prepare(for segue: UIStoryboardSegue, sender: Any) {
// ...
detailController.item = newItem
}
perform block 将在上下文的队列上执行,该队列是主队列,这将使从闭包中抓取对象并进行 segue 安全,对吧?
2)还是这个?
context.performAndWait {
newItem = Item(context: context)
try! context.save()
}
performSegue(...)
对于1) 和2):如果这不是主要上下文怎么办?我能否将对象传输到主线程/ View Controller ?
3)抓取FRC委托(delegate)中的对象:
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
// Assuming insert
new Item = object
performSegue(...)
}
我怎么知道 object
是我刚插入并想继续使用的对象,而不仅仅是通过其他方式插入的某个对象?我可以确定当我插入一个对象时,对委托(delegate)方法的下一次调用将引用该对象吗?可能有一个并行上下文插入一个元素...
引用
我正在尝试重新创建没有核心数据的基本设置:
class MasterViewController: UITableViewController {
var tableViewData = [Item]()
let newItem: Item?
// On user button press
func addItem(_ sender: Any) {
newItem = Item()
tableViewData.append(newItem)
tableView.reloadData()
performSegue(withIdentifier: "showDetail")
}
func prepare(for segue: UIStoryboardSegue, sender: Any) {
// ...
detailController.item = newItem
}
}
最佳答案
在我看来,这可能更清楚:
//On user button press
func addItem() {
performSegue(withIdentifier: "showDetail")
}
func prepare(for segue: UIStoryBoardSegue, sender: Any) {
if segue.identifier == "showDetail" {
//create the item(managedobject), save the context
//feed the item to the destination viewcontroller who needs it
}
}
这样你就知道你 segue 的对象是正确的,并且你的逻辑更紧密。
引用上下文。当您创建一个 managedObjectContext 时,您指定了您将如何使用它(主要的或私有(private)的),并且您必须坚持这一点。最好的做法是拥有一个上下文,即您向下传递 View Controller 层次结构。
当您开始考虑将设备上的数据与后端数据库同步时,您可能需要第二个上下文,我认为现在还不是这样。 您可能希望将第二个上下文设为私有(private)队列,然后您才需要担心将托管对象映射到正确的上下文。
在那之前,你唯一的上下文是一只非常友好的动物。
关于ios - 核心数据 : Segue to detail controller with newly created ManagedObject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44495769/