ios - 核心数据 : Segue to detail controller with newly created ManagedObject

标签 ios objective-c swift uitableview core-data

情况

  1. 用户点击按钮将项目添加到 TableView 。
  2. 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/

相关文章:

ios - 单独文件中的类别给了我 "linker command failed with exit code 1 (use -v to see invocation)"

ios - 如何在 AVPlayer 中提取 MPMediaItemCollection 到 NSData?

ios - 从返回 NSArray 的 Swift 覆盖 Obj-C 类方法

swift - 通过添加 List() 和另一个模型类来执行迁移

ios - 大资源APP分发管理策略

ios - 照片错误 : Unable to obtain assetsd XPC proxy 是什么意思

ios - 将 NSString[] 粘贴到 NSArray 中

ios - TestFlight Beta 应用程序审查

objective-c - iPhone 6s plus 设备中的 UIPickerView UI 和功能问题

ios - 当我以编程方式进行 segue 时,UIBarButtonItem 不会显示