数据不会加载到我的 Table 视图中

Data won't load into my Table View

所以我的笔记应用程序有一个 UITableViewController class,其中一切正常,添加、删除和编辑 table 视图。但现在我正在尝试使用 "Realm" 数据库加载数据。我是 iOS (Swift) 的新手,尤其是 Realm,所以我有点困惑。我把它完美地保存到数据库中,当我单击导航栏中的 "Save" 按钮时它就会显示出来。但是当我重新启动应用程序时,table 视图完全是空的。我已经坚持了一段时间,尝试了到目前为止我所知道的一切,但就是无法让它显示出来。有人可以帮助我,也许可以告诉我我做错了什么,或者根本没有做吗?非常感谢。

这也是我的 class

import UIKit
import Realm

class NoteTableViewController: UITableViewController {

    // MARK: Properties

    var notes = [Note]() // Initialized with a default value (an empty array of Note objects).

    override func viewDidLoad() {
        super.viewDidLoad()

        // Get Realm Database location
        println(RLMRealm.defaultRealm().path)

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // Return the number of sections.
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // Return the number of rows in the section.
        return notes.count
    }


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        // Table view cells are reused and should be dequeued using a cell identifier.
        let cellIdentifier = "NoteTableViewCell"
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! NoteTableViewCell

        // Fetches the appropriate note for the data source layout in the notes array
        let note = notes[indexPath.row]

        // Configure the cell...
        cell.titleLabel.text = note.title
        cell.bodyLabel.text = note.body

        return cell
    }



    // Override to support conditional editing of the table view.
    override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        // Return NO if you do not want the specified item to be editable.
        return true
    }



    // Override to support editing the table view.
    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {
            // Delete the row from the data source
            notes.removeAtIndex(indexPath.row)

            // Get the default Realm (Will do this part later)
            /*
            let realm = RLMRealm.defaultRealm()
            realm.beginWriteTransaction()

            realm.deleteObject(notes[Int(indexPath.row)])
            realm.commitWriteTransaction()
            */

            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        } else if editingStyle == .Insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }
    }


    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "ShowDetail" { // Clicked on a cell
            let noteDetailViewController = segue.destinationViewController as! NoteViewController
            // Get the cell that generated this segue.
            if let selectedNoteCell = sender as? NoteTableViewCell {
                let indexPath = tableView.indexPathForCell(selectedNoteCell)!
                let selectedNote = notes[indexPath.row]
                noteDetailViewController.note = selectedNote
            }
        }
        else if segue.identifier == "AddItem" { // Clicked add button
            println("Adding new note")
        }
    }


    @IBAction func unwindToNoteList(sender: UIStoryboardSegue) {
        if let sourceViewController = sender.sourceViewController as? NoteViewController, note = sourceViewController.note {
            if let selectedIndexPath = tableView.indexPathForSelectedRow() { // User clicked on a row
                // Update an existing note.
                notes[selectedIndexPath.row] = note

                tableView.reloadRowsAtIndexPaths([selectedIndexPath], withRowAnimation: .None)
            }
            else {
                // Add a new note.
                let newIndexPath = NSIndexPath(forRow: notes.count, inSection: 0)
                notes.append(note)

                // Persist in database
                let realm = RLMRealm.defaultRealm()
                realm.beginWriteTransaction()
                Note.createInRealm(realm, withValue: notes[newIndexPath.row])
                realm.commitWriteTransaction()

                tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Bottom)
            }
        }
    }

}

而这个是笔记对象class

import UIKit // Automatically imports Foundation
import Realm

class Note: RLMObject {

    // MARK: Properties

    dynamic var title: String = ""
    dynamic var body: String = ""

    // MARK: Initialization

    init?(title: String, body: String) { // Failable initializer


        // Initialize stored properties.
        self.title = title
        self.body = body

        super.init()

        // Initialization should fail if there is no title
        if title.isEmpty {
            return nil
        }

    }

    // Must have for Realm to work
    override init() {
        super.init()
    }

}

又过了 2 天就解决了...这是我更新的 class

如 Swinny89 所说,从所有对象中的新笔记对象开始,而不是初始化 "empty" 笔记数组。

import UIKit
import Realm

class NoteTableViewController: UITableViewController {

  // MARK: Properties

    var notes = Note.allObjects()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Get Realm Database location
        println(RLMRealm.defaultRealm().path)

    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // Return the number of sections.
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // Return the number of rows in the section.
        return Int(notes.count)
    }


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        // Table view cells are reused and should be dequeued using a cell identifier.
        let cellIdentifier = "NoteTableViewCell"
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! NoteTableViewCell

        let object = notes[UInt(indexPath.row)] as! Note

        // Configure the cell...
        cell.titleLabel.text = object.title
        cell.bodyLabel.text = object.body

        return cell
    }

    // Override to support conditional editing of the table view.
    override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        // Return NO if you do not want the specified item to be editable.
        return true
    }

    // Override to support editing the table view.
    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {

            // Delete from database
            let realm = RLMRealm.defaultRealm()
            realm.beginWriteTransaction()
            realm.deleteObject(notes[UInt(indexPath.row)] as! RLMObject)
            realm.commitWriteTransaction()

            // Delete row from table view
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        } else if editingStyle == .Insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }
    }

    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "ShowDetail" { // Clicked on a cell
            let noteDetailViewController = segue.destinationViewController as! NoteViewController
            // Get the cell that generated this segue.
            if let selectedNoteCell = sender as? NoteTableViewCell {
                let indexPath = tableView.indexPathForCell(selectedNoteCell)!

                let selectedNote = notes[UInt(indexPath.row)] as! Note
                noteDetailViewController.note = selectedNote

            }
        }
        else if segue.identifier == "AddItem" { // Clicked add button
            println("Adding new note")
        }
    }

    @IBAction func unwindToNoteList(sender: UIStoryboardSegue) {
        if let sourceViewController = sender.sourceViewController as? NoteViewController, note = sourceViewController.note {

            let uuid = NSUUID().UUIDString // Needed for primary key. see below

            var unwindedNote = Note()

            if let selectedIndexPath = tableView.indexPathForSelectedRow() { // User clicked on a row

                // Updating of the note is done in NoteViewController

                tableView.reloadRowsAtIndexPaths([selectedIndexPath], withRowAnimation: .None)
            }
            else {
                // Add a new note.
                let newIndexPath = NSIndexPath(forRow: Int(notes.count), inSection: 0)

                // Persist in database
                let realm = RLMRealm.defaultRealm()
                realm.beginWriteTransaction()

                unwindedNote.title = note.title
                unwindedNote.body = note.body
                unwindedNote.id = uuid // This is done for the primary key that Realm needs, unique for each object created.

                realm.addObjects([unwindedNote])
                realm.commitWriteTransaction()

                tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Bottom)
            }
        }
    }
}

这是因为您的 Note 数组被初始化为一个空数组,这就是您用来告诉 tableView 有多少行,即 0。

一旦您的 Note 数组已设置并拥有一些数据,您就可以调用 tableView.reloadData() 以重新加载包含数据的数组。

此外,查看上面的代码,您的 class 是从 UITableViewController 继承的,而不是实现 UITableViewControllerDelegateUITableViewControllerDataSource。一旦您的 class 实现了这些,您需要确保在情节提要中或通过代码将 viewController 设置为 tableViewController 的数据源和委托。