菜鸟教程小白 发表于 2022-12-13 15:01:21

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


                                            <p><p>我有一个基于表格 View 的应用程序,它有一个 MasterTableViewController 和一个 DetailChildTableViewController。</p>

<p>MasterTableViewController 在导航栏中有一个 +,因此用户可以看到在文本字段中输入该文件夹的名称的 View 。用户完成后,时钟完成,然后使用 Core Data 存储此文件夹,并在 MasterTableViewController 中显示此新文件夹。</p>

<p>这里是这个特定 TableViewController 的代码</p>

<p><strong>MasterTableViewController</strong></p>

<pre><code>   class MasterTableViewController: UITableViewController, NSFetchedResultsControllerDelegate {


let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
var fetchedResultsController : NSFetchedResultsController = NSFetchedResultsController()

// Populate fetched results controller
func getFetchedResultController() -&gt; NSFetchedResultsController {

    fetchedResultsController = NSFetchedResultsController(fetchRequest: taskFetchRequest(), managedObjectContext: managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)

    return fetchedResultsController

}


func taskFetchRequest() -&gt; NSFetchRequest {

    let fetchRequest = NSFetchRequest(entityName: &#34;Folder&#34;)
    let sortDescriptor = NSSortDescriptor(key: &#34;name&#34;, ascending: true)


    fetchRequest.sortDescriptors =
    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....
</code></pre>

<p>这个 Controller 中的其余代码只有在表格 View 单元格中显示数据的方法和一个 segue 方法,当用户点击新创建的单元格对象时,它将核心数据名称传递给下一个 ViewController 。</p>

<p>这是创建此特定对象以保存并显示在 MasterTableViewController 上的代码</p>

<p><strong>AddViewController</strong></p>

<pre><code>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(&#34;Folder&#34;, 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(&#34;Successfully Saved \n&#34;)
    } catch _ {
    }
}

}
</code></pre>

<p>所以这段代码基本上保存了新输入的文件夹并关闭了文件夹名称 View ,MasterTableViewController 显示了这个新文件夹。</p>

<p>问题在于 <strong>DetailChildTableViewController</strong>,它是 MasterTableViewController 中创建的每个 <strong>Folder</strong> 的详细信息。</p>

<p>这是最终tableview Controller的代码</p>

<p>** DetailChildTableViewController**</p>

<pre><code>   class DetailChildTableViewController: UITableViewController, UIPopoverPresentationControllerDelegate, NSFetchedResultsControllerDelegate {

let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext

var fetchedResultsController : NSFetchedResultsController = NSFetchedResultsController()

// Populate fetched results controller
func getFetchedResultController() -&gt; NSFetchedResultsController {

    fetchedResultsController = NSFetchedResultsController(fetchRequest: taskFetchRequest(), managedObjectContext: managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)

    return fetchedResultsController

}


func taskFetchRequest() -&gt; NSFetchRequest {

    let fetchRequest = NSFetchRequest(entityName: &#34;List&#34;)
    let sortDescriptor = NSSortDescriptor(key: &#34;itemListName&#34;, ascending: false)


    fetchRequest.sortDescriptors =
    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) -&gt; Int {

    if let sections = fetchedResultsController.sections {
      return sections.count
    }

    return 0
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {

    if let sections = fetchedResultsController.sections {
      let currentSection = sections
      return currentSection.numberOfObjects
    }

    return 0
}

}
</code></pre>

<p>此 DetailChildTableViewController 在导航栏中也有一个 + 按钮,并会弹出一个类似的 AddViewController 以使用相同的 Core Data 方法将数据添加到此特定文件夹。</p>

<p>问题是当我在我的 MasterTableViewController 中创建 2 个实体时,例如:</p>

<ul>
<li>Folder_One</li>
<li>Folder_Two</li>
</ul>

<p>我进入 <strong>Folder_Two</strong> 并在此文件夹中创建一个列表对象,然后返回 MasterTableViewController 然后选择 <strong>Folder_One</strong>,它仍然显示相同的列表对象我在 <strong>Folder_Two</strong> 中创建。</p>

<p>我该如何解决这个简单但不清楚的问题?</p>

<p>顺便说一下,这是我的数据模型:</p>

<p><strong>TestApp.xcdatamodel</strong></p>

<p>实体:</p>

<ol>
<li>文件夹</li>
<li><p>列表</p>

<p>属性:
<strong>name</strong> 类型为 String(用于 <strong>Folder</strong> 实体)
<strong>itemListName</strong> 类型为 String(用于 <strong>List</strong> 实体)</p>

<p>关系:(对于<strong>文件夹</strong>实体)
关系<em>目的地</em>:列表</p></li>
</ol>

<p>请注意,列表实体未列为与文件夹有关系。我将 <strong>Folder</strong> 设置为与 <strong>List</strong> 的关系为 <strong>一对多</strong> 关系。</p>

<p>我做错了什么,我该如何处理?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>问题是您的 <code>DetailChildTableViewController</code> 显示 <em>所有</em> <code>List</code> 对象。您需要将其限制为仅获取与当前 <code>Folder</code> 相关的 <code>List</code> 对象。为此,您必须具有从 <code>List</code> 到 <code>Folder</code> 的关系。这种关系是一对一的,并且是从 <code>Folder</code> 到 <code>List</code> 的一对多关系的逆。 (您几乎应该总是为每个关系创建一个逆向关系。即使您觉得不需要它,也要创建它。在这种情况下,正如您将在下面看到的那样,您确实需要它)。所以你的实体模型应该是这样的:</p>

<pre><code>Folder          List
======          ====
name            itemListName
lists &lt;------&gt;&gt; folder
</code></pre>

<p>在您的 <code>DetailChildTableViewController</code> 中,添加一个新变量,该变量将是您正在为其显示 <code>Lists</code> 的 <code>Folder</code>:</p>

<pre><code>var currentFolder : Folder?
</code></pre>

<p>要限制提取使其仅显示与此文件夹相关的 <code>List</code> 对象,请在提取请求中添加谓词:</p>

<pre><code>if let thisFolder = currentFolder {
    fetchRequest.predicate = NSPredicate(format:&#34;folder == %@&#34;,thisFolder)
}
</code></pre>

<p>当用户点击 <code>MasterTableViewController</code> 中的单元格时,在显示 <code>DetailChildTableViewController</code> 之前,您必须为 <code>currentFolder</code> 设置正确的值。在 <code>prepareForSegue</code> 中,您将需要如下内容:</p>

<pre><code>let indexPath = self.tableView.indexPathForSelectedRow!
let currentFolder = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Folder
detailViewController.currentFolder = currentFolder
</code></pre>

<p>同样,<code>AddListViewController</code> 必须有一个 <code>currentFolder</code> 变量来知道新创建的 <code>List</code> 应该属于哪个 <code>Folder</code>到(并且 <code>DetailChildTableViewController</code> 中的代码必须设置 <code>currentFolder</code> 的值)。在<code>AddListViewController</code>中,存储<code>List</code>项时,需要设置关系:</p>

<pre><code>newList.folder = currentFolder
</code></pre>

<p>请注意,当您设置关系时,CoreData 会自动设置反向关系(假设您定义了一个)。所以 <code>newList</code> 将被添加到 <code>currentFolder</code> 的 <code>lists</code> 属性中。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 核心数据一对多关系不存储其数据,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/35789718/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/35789718/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 核心数据一对多关系不存储其数据