【问题标题】:Read the value of an attribute of a Core Data entity读取核心数据实体的属性值
【发布时间】:2017-11-04 15:58:48
【问题描述】:

我正在尝试读取存储在核心数据数据库中的实体(称为“列表”)的属性(称为“名称”)的值。我遇到的问题是它说该属性的值为 nil,它应该是一个字符串。

我检索所有列表实体的代码如下:

container?.performBackgroundTask { [weak self] context in
    self?.wordLists = try! List.all(in: context)
    DispatchQueue.main.async(execute: {
        print("Main queue available, reloading tableview.")
        self?.wordListSelector.reloadData()
    })
}

class func all(in context: NSManagedObjectContext) throws -> [List] {
    let listRequest: NSFetchRequest<List> = List.fetchRequest()
    do {
        let list = try context.fetch(listRequest)
        print(list)
        return list
    } catch {
        print("error")
        throw error
    }
}

打印出来:

[<__Words.List: 0x6000000937e0> (entity: List; id: 0xd00000000004000c <x-coredata://999D0158-64BD-44FD-A0B1-AB4EC03B9386/List/p1> ; data: <fault>), <__Words.List: 0x600000093a60> (entity: List; id: 0xd00000000008000c <x-coredata://999D0158-64BD-44FD-A0B1-AB4EC03B9386/List/p2> ; data: <fault>), <__Words.List: 0x600000093ab0> (entity: List; id: 0xd0000000000c000c <x-coredata://999D0158-64BD-44FD-A0B1-AB4EC03B9386/List/p3> ; data: <fault>)]

这表明数据库中应该有 3 个列表,这是预期的。

我已经创建了一个这样的变量:

var wordLists: [List] = [] {
    didSet {
        print("Detected wordList update, waiting for main queue.")
        DispatchQueue.main.async(execute: {
            print("Main queue available, reloading tableview.")
            self.wordListSelector.reloadData()
        })
    }
}

这个变量保存了我通过调用前面提到的 all() 函数检索到的列表实体。

以下两种方法将填充我的 TableView:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    print("numberOfRowsInSection: \(wordLists.count).")
    return wordLists.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cellIdentifier = "CategoryCell"
    let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath)

    print("cellForRowAt: \(indexPath.row) has name \(wordLists[indexPath.row].name).")
    cell.textLabel?.text = wordLists[indexPath.row].name

    return cell
}

这将打印以下内容:

Detected wordList update, waiting for main queue.
Main queue available, reloading tableview.
numberOfRowsInSection: 3.
cellForRowAt: 0 has name nil.
cellForRowAt: 1 has name nil.
cellForRowAt: 2 has name nil.

为什么这个名字是零?这是因为数据仍然“错误”吗?通过在线查看主题,我认为 Core Data 在您尝试访问它时会自动对其数据进行无故障处理。我做错了什么?

编辑:

如果我将 didset 更改为以下内容:

var wordLists: [List] = [] {
    didSet {
        print("Wordlist was updated.")
        for wordList in wordLists {
            print(wordList)
            print(wordList.name)
        }
    }
}

它会打印名称(可选(“nameofitem1”))。在 cellForRowAt 中,它仍然打印“nil”。

【问题讨论】:

  • 我不将didSet 观察者用于数据源数组。获取数据后重新加载表格视图。
  • 好的,我会改变它,很好的观察:)除此之外,任何想法为什么我得到一个“nil”值而不是实际名称?
  • 请您显示您实际填充 WordLists 数组的代码吗?你是对的,当你访问属性时,CD 应该自动触发 List 对象的错误。但如果您从错误的线程访问它们,它可能无法做到这一点。您的 didSet 使用调度异步这一事实表明您可能确实在混合线程。
  • 我添加了填充 wordList 数组的代码。我还将 didSet 更改为 forloop。这个 forloop 确实打印了名称。

标签: swift core-data


【解决方案1】:

对于 NSFetchedResultsController,您所做的工作看起来不错。这也将有助于您可能按照 cmets 中的建议混淆线程。 NSFetchedResultsController 上有非常好的文档

【讨论】:

  • 啊,谢谢!我已经实现了 NSFetchResultsController 并且工作正常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多