核心数据一对多关系不存储其数据

我有一个基于表视图的应用程序,它有一个MasterTableViewController和一个DetailChildTableViewController。

MasterTableViewController在导航栏中有一个+,这样用户就可以看到在文本框中input该文件夹的名称。 一旦用户完成,完成的时钟和这个文件夹,然后存储使用核心数据,并显示在MasterTableViewController这个新的文件夹。

这是这个特定的TableViewController的代码

MasterTableViewController

class MasterTableViewController: UITableViewController, NSFetchedResultsControllerDelegate { let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext var fetchedResultsController : NSFetchedResultsController = NSFetchedResultsController() // Populate fetched results controller func getFetchedResultController() -> NSFetchedResultsController { fetchedResultsController = NSFetchedResultsController(fetchRequest: taskFetchRequest(), managedObjectContext: managedObjectContext, sectionNameKeyPath: nil, cacheName: nil) return fetchedResultsController } func taskFetchRequest() -> NSFetchRequest { let fetchRequest = NSFetchRequest(entityName: "Folder") let sortDescriptor = NSSortDescriptor(key: "name", ascending: true) fetchRequest.sortDescriptors = [sortDescriptor] return fetchRequest } } override viewDidLoad(){ fetchedResultsController = getFetchedResultController() fetchedResultsController.delegate = self do { try fetchedResultsController.performFetch() } catch _ { } } // Table View Methods to show data in Custom UITableViewCell and Segue method.... 

在这个控制器中的其余代码只是有方法来显示表视图单元格中的数据和一个segue方法,当用户点击新创build的单元格对象时,将核心数据名称传递到下一个视图控制器。

这里是创build这个特定的对象来保存和显示在MasterTableViewController上的代码

AddViewController

 class addItemTableViewController: UITableViewController { @IBOutlet weak var FolderName: UITextField! // Use the same managed object to save let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext @IBAction func Done(sender: AnyObject){ // Calling a function to save the folder to core data saveFolder() self.dismissViewControllerAnimated(true, completion: nil) } // Function that saves func saveFolder(){ let entityDescription = NSEntityDescription.entityForName("Folder", inManagedObjectContext: managedObjectContext) let item = Folder(entity: entityDescription!, insertIntoManagedObjectContext: managedObjectContext) item.name = FolderName.text! // Passed Value of the color picker table view below do { try managedObjectContext.save() print("Successfully Saved \n") } catch _ { } } } 

所以这段代码基本上保存了新input的文件夹并closures文件夹名称视图,MasterTableViewController显示这个新文件夹。

问题在于DetailChildTableViewController ,它是在MasterTableViewController中创build的每个文件夹的细节。

这里是最终的tableview控制器的代码

** DetailChildTableViewController **

  class DetailChildTableViewController: UITableViewController, UIPopoverPresentationControllerDelegate, NSFetchedResultsControllerDelegate { let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext var fetchedResultsController : NSFetchedResultsController = NSFetchedResultsController() // Populate fetched results controller func getFetchedResultController() -> NSFetchedResultsController { fetchedResultsController = NSFetchedResultsController(fetchRequest: taskFetchRequest(), managedObjectContext: managedObjectContext, sectionNameKeyPath: nil, cacheName: nil) return fetchedResultsController } func taskFetchRequest() -> NSFetchRequest { let fetchRequest = NSFetchRequest(entityName: "List") let sortDescriptor = NSSortDescriptor(key: "itemListName", ascending: false) fetchRequest.sortDescriptors = [sortDescriptor] return fetchRequest } override func viewDidLoad() { super.viewDidLoad(){ // Core data fetchedResultsController = getFetchedResultController() fetchedResultsController.delegate = self do { try fetchedResultsController.performFetch() } catch _ { } self.tableView.reloadData() } // MARK: - Display the results in table view override func numberOfSectionsInTableView(tableView: UITableView) -> Int { if let sections = fetchedResultsController.sections { return sections.count } return 0 } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if let sections = fetchedResultsController.sections { let currentSection = sections[section] return currentSection.numberOfObjects } return 0 } } 

这个DetailChildTableViewController在导航栏中也有一个+button,并且带来了一个类似的AddViewController来使用相同的Core Data方法向这个特定的文件夹添加数据。

问题是,当我在我的MasterTableViewController中创build2个实体,例如说:

  • Folder_One
  • Folder_Two

我进入Folder_Two并在这个文件夹中创build一个列表对象,然后返回到MasterTableViewController,然后selectFolder_One ,它仍然显示我在Folder_Two中创build的同一个列表对象。

我怎样才能解决这个简单但不清楚的问题?

这里是我的数据模型的方式:

TestApp.xcdatamodel

实体:

  1. 名单

    属性:Stringtypes的名称 (用于Folder实体) itemListNametypes的String(用于List实体)

    关系:(对于文件夹实体)关系目标 :列表

请注意列表实体没有被列为与文件夹的关系。 我设置文件夹作为一对多的关系与列表的关系。

我做错了什么,我该怎么办?

问题是你的DetailChildTableViewController显示所有List对象。 您需要将其限制为仅提取与当前Folder相关的List对象。 要做到这一点,你必须有从ListFolder的关系。 这种关系将是一对一的,并且是从FolderList的一对多关系的逆转。 (你应该几乎总是为每一个关系创build一个逆向,即使你觉得你不需要它,也要创build它,在这种情况下,你将会看到下面的例子)。 所以你的实体模型应该是这样的:

 Folder List ====== ==== name itemListName lists <------>> folder 

在你的DetailChildTableViewController ,添加一个新的variables,这个variables将是你正在显示ListsFolder

 var currentFolder : Folder? 

为了限制提取,所以它只显示与这个文件夹相关的List对象,向提取请求添加一个谓词:

 if let thisFolder = currentFolder { fetchRequest.predicate = NSPredicate(format:"folder == %@",thisFolder) } 

当用户点击MasterTableViewController的单元格时,在显示DetailChildTableViewController之前,必须为currentFolder设置正确的值。 在prepareForSegue ,你将需要像这样的东西:

 let indexPath = self.tableView.indexPathForSelectedRow! let currentFolder = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Folder detailViewController.currentFolder = currentFolder 

同样, AddListViewController必须有一个currentFoldervariables来知道新创build的List应该属于哪个Folder (并且DetailChildTableViewController中的代码必须设置currentFolder的值)。 在AddListViewController ,当你存储List项目时,你需要设置关系:

 newList.folder = currentFolder 

请注意,设置关系时,CoreData将自动设置反比关系(假设您定义了一个关系)。 所以newList将被添加到currentFolderlists属性中。