在 TableView 中实现 CoreData 时遇到问题

Posted

技术标签:

【中文标题】在 TableView 中实现 CoreData 时遇到问题【英文标题】:Trouble Implementing CoreData into a TableView 【发布时间】:2017-05-31 11:55:06 【问题描述】:

我遵循了有关实现离线数据的 Apple 开发人员教程。但我想使用 CoreData。我正在努力打开 CoreData 上下文并将其放入数组中,如果这是正确的话。

我正在使用 Swift 3 和最新的 xCode。

这是我的实体,我不需要为单元格提取所有值,只需要显示有趣的东西:

所以这是我的 book.swift,一切都基于它。

import Foundation
import CoreData
import UIKit
import os.log

public class book: NSObject, NSCoding 
var title: String
var author: String
var photo: UIImage?
var isbn: String
var publisher: String

static let DocumentsDirectory = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first!
static let ArchiveURL = DocumentsDirectory.appendingPathComponent("books")


struct PropertyKey 
    static let title = "title"
    static let photo = "photo"
    static let author = "author"
    static let isbn = "isbn"
    static let publisher = "publisher"

然后,我的 BookTableViewController

import UIKit
import os.log
import CoreData

class BookTableViewController: UITableViewController 

//MARK: Properties
var books = [book]()
var i = 0
var managedObjectContext: NSManagedObjectContext

required init(coder aDecoder: NSCoder) 
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    self.managedObjectContext = appDelegate.persistentContainer.viewContext
    super.init(coder: aDecoder)!


override func viewDidLoad() 
    super.viewDidLoad()
    

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

    guard let cell = tableView.dequeueReusableCell(withIdentifier: "BookTableViewCell", for: indexPath) as? BookTableViewCell else 
        fatalError("some cell error")
    
    // need help here, somehow grab the data from CoreData, or do I populate the book array from CoreData?


    let book = books[indexPath.row]

    cell.bookLabel.text = book.title
    cell.authorLabel.text = book.author
    cell.bookImageView.image = book.photo
    cell.publisherLabel.text = book.publisher

    return cell

我所理解的是我需要以某种方式在 cellforrowat 中打开一个循环(至少我认为),或者我是否需要在 superviewdidload 中更早地填充数组?

我对 CoreData 进行了大量研究,但仍然没有完全理解它。

【问题讨论】:

你在哪里从 coredata 获取数据? 您确实应该在表格视图的数据源中使用 NSFetchedResultsController。试试看,真的很简单。 @KKRocks 我不确定如何从 CoreData 获取数据,这就是我的困惑。 @Abizern 我尝试设置它,但不知道实际发生了什么,以及如何为我的项目修复它。 【参考方案1】:

你的book 类被声明为

public class book: NSObject, NSCoding

它不是NSManagedObject 的子类,因此您不能将它与Core Data 一起使用。使用 Core Data 存储的所有对象都必须是 NSManagedObject 或子类的实例。

稍后你会这样做:

let book = books[indexPath.row] as! NSManagedObject

由于booksbook 的数组,它不是NSManagedObject 的子类,因此肯定会失败。您不能使用as! 将您的类的实例转换为NSManagedObject。它们是完全不同的类型。

在 Xcode 的最新版本中,NSManagedObject 的子类会自动创建。您的数据模型显示了一个名为 Book 的实体,这意味着 Xcode 将自动创建一个与实体描述匹配的类 Book。您应该使用该类而不是您创建的 book 类。使用该类,您可以从托管对象上下文中创建、保存和获取 Book 的实例。

您似乎对 Core Data 的一些最基本方面有困难。我强烈建议查看 Apple 的 Core Data Programming Guide。它详细介绍了核心数据,包括示例代码。在您掌握基础知识之前,您将很难使用 Core Data,而该指南将帮助您做到这一点。

【讨论】:

【参考方案2】:

你把代码弄乱了,你不需要创建一些新的继承 NSObject 的类书,你可以使用 NSManagedObject aka Book aka CoreDataModel entity aka 我不知道还有什么。 每当在 collectionView 或 tableView 或任何使用某种 dataSource 协议的组件中与 Coredata 进行交互时,您都应该真正使用 NSFetchedResultsController...无论如何我觉得本教程对初学者非常有用:

https://cocoacasts.com/implement-the-nsfetchedresultscontrollerdelegate-protocol-with-swift-3/

只需按照教程并删除课程书(你不应该创建第一个字母小写的课程......它真的不符合惯例。你可以将所有属性存储到 NSManagedObject 中(如果你手动生成文件)

【讨论】:

以上是关于在 TableView 中实现 CoreData 时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

在 TableView 中实现表单

如何在 tableView 单元格中实现收藏按钮?

如何使用不同的委托和数据源方法在一个类中实现两个Tableview?

如何在 TableView QtQuick.Controls 2.4 中实现 TableView QtQuick.Controls 1.4 的 Selectable future

如何在 Qt TableView 中实现像过滤一样的电子表格?

在A section tableview中实现加载更多