关系属性的核心数据获取请求

Posted

技术标签:

【中文标题】关系属性的核心数据获取请求【英文标题】:Core data Fetch request on relationship properties 【发布时间】:2015-12-13 16:12:24 【问题描述】:

我的应用程序有许多单词列表,每个单词列表都包含许多单词。在一个视图控制器中,一个 tableView 列出了 wordList,然后一个子视图控制器有一个 tableView,里面有单词。 segue 传递 wordList 实体。但我无法弄清楚如何对传递的 wordList 执行获取请求,然后获取所有单词。错误信息如下所示。我需要执行获取请求而不是查看属性,以便进行排序。

在此先感谢您对此提供的任何帮助....

WordList实体有一个属性listName,关系:words,destination:Word,Inverse:wordList

Word实体有一个属性wordName、wordIndex和关系:wordList,destination:WordList,Inverse:words

我的 WordsViewController 看起来像:

class WordsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate  

var coreDataStack: CoreDataStack = (UIApplication.sharedApplication().delegate as! AppDelegate).coreDataStack

var wordList: WordList?
var words = [Word]()
var word: Word?

override func viewDidLoad() 
    super.viewDidLoad()

    // set the title of the scene
    title = wordList?.listName

   // fetch all the words that are part of the wordList passed to this VC.
   let fetchRequest = NSFetchRequest(entityName: "Word")
    let wordListPredicate = NSPredicate(format: "word.wordList == '\(wordList)'") // GIVES AN ERROR SAYING UNABLE TO PARSE THE FORMAT STRING "word.wordList == 'Optional(<WordList:0x...

    let sortDescriptor = NSSortDescriptor(key: "wordIndex", ascending: true)
    fetchRequest.sortDescriptors = [sortDescriptor]

    fetchRequest.predicate = wordListPredicate

    do 
        if let results = try coreDataStack.managedObjectContext.executeFetchRequest(fetchRequest) as? [Word] 
            words = results
        
     catch 
        fatalError("There was an error fetching system person")
      

【问题讨论】:

【参考方案1】:

您不能使用字符串插值来构建谓词,请使用 取而代之的是参数替换。在您的情况下(因为 var wordList: WordList? 是 可选):

if let theWordlist = wordlist 
    let wordListPredicate = NSPredicate(format: "wordList == %@", theWordlist)
 else 
    // wordlist is nil ...

还要注意谓词中的"word.wordList == " 应该是 "wordList == ",因为“wordList”是“Word”的属性 实体。

欲了解更多信息,请参阅Predicate Format String Syntax 在“谓词编程指南”中。

【讨论】:

【参考方案2】:

您应该使用NSFetchedResultsController,而不是获取viewDidLoad 中的所有数据。 fetched results controller 将帮助您有效地获取和显示数据、对更改做出反应、优化内存等。

在获取结果控制器的获取请求(获取实体Word)中,使用此谓词(如果您的可选wordListnil,则使用安全措施):

request.predicate = wordList != nil ?
  NSPredicate(format: "wordlist = %@", wordList!) :
  NSPredicate(value: false)

这假设单词列表与其单词之间存在一对多关系。我会推荐这种设置,即使这意味着如果同一个单词位于不同的列表中,您可能必须多次存储它。

注意:false 谓词确保您获得有效的获取请求,但不会获取任何内容。

【讨论】:

wordlist == nil 的情况可能是一个编程错误,然后——在我看来——崩溃总比“默默地”什么都不显示要好。 没错,这也许也是风格问题。

以上是关于关系属性的核心数据获取请求的主要内容,如果未能解决你的问题,请参考以下文章

核心数据 - 以一对多关系访问实例与获取请求?

核心数据:以一对多的关系获取实体的获取请求

获取“最新”单个实体的最简单 Fetch 请求 - 核心数据

从核心数据获取请求中排除反向关系

具有特殊限制的核心数据获取关系计数

从多对多关系中获取核心数据