Home>

I have a question about a Todo app that uses a simple TableView.

As the function of the application, Realm and NavigationController are the parents in the DB, and
Place TableViewController on the list screen.
When a cell is selected, the code transitions to the edit screen and the edited value is returned to the list screen.

I have a question from here
Display the contents of Todo registered in the app numberOfRowsInSection, cellForRowAt, didSelectRowAt
Since the search process is inserted each time,
For example, if 7 cells are displayed on the screen when the application is started, the search will be executed 8 times or more.

It is good as long as the data is small, but as the registered data increases, the load will increase proportionally, so
I want to perform the search process only when the screen is displayed. Is there a possible method?

  • Answer # 1

    At the very least, I think it would have been better if you provided the current code in advance.

    The point is every timerealm.object ()I guess it is a problem of accessing with.

    The important thing about handling Realm isobject ()The value obtained with is a managed object, which means that you can always get the latest data every time you access it (auto update or live update).

    Working with Realm objects --Auto-updating objects

    However,object ()As for the values ​​returned by, the order of the contents is not always guaranteed, so it is necessary to set a primary key in the model and devise so that it can always be obtained in a sorted state.

    In addition, you need to set an observer to see if the property value has been updated, for example in it.tableView.reloadData ()It is necessary to devise such as calling.

    Notifications --Realm notifications

    If you make a simple sample against these backgrounds, it might look like the following, for example.

    However, all error handlingtry!It is simplified with, and the observer processing ignores the value passed to the closure, so I think that the questioner, h.h, needs to devise this.

    import UIKit
    import RealmSwift
    class Todo: Object {
        @objc dynamic var task = ""
        @objc dynamic var id = 0
        override static func primaryKey ()->String? {
            return "id"
        }
    }
    class ViewController: UIViewController {
        var todos: Results<Todo>!
        // Token to receive update notification
        // see https://realm.io/docs/swift/latest/#object-notifications
        var token: NotificationToken!
        @IBOutlet weak var todoTableView: UITableView! {
            didSet {
                todoTableView.dataSource = self
                todoTableView.register (UITableViewCell.self, forCellReuseIdentifier: "cell")
            }
        }
        override func viewDidLoad () {
            super.viewDidLoad ()
            let realm = try! Realm ()
            todos = realm.objects (Todo.self) .sorted (byKeyPath: "id")
            // Describe the processing to be performed when it is updated.
            // For more information->https://realm.io/docs/swift/latest/#object-notifications
            token = realm.observe {_, _ in
                self.todoTableView.reloadData ()
            }
        }
        // I intend to add TODO
        @IBAction func addButton (_ sender: UIButton) {
            var id: Int
            // Set id to 1 if no data exists.
            // If any data already exists, add 1 to the newest id to make the next id
            if let firstTodo = todos.last {
                id = firstTodo.id + 1
            } else {
                id = 1
            }
            // add a new TODO
            let todo = Todo ()
            todo.id = id
            todo.task = Int.random (in: 100 ... 999) .description
            let realm = try! Realm ()
            try! realm.write {
                realm.add (todo)
            }
        }
    }
    extension ViewController: UITableViewDataSource {
        func tableView (_ tableView: UITableView, numberOfRowsInSection section: Int)->Int {
            return todos.count
        }
        func tableView (_ tableView: UITableView, cellForRowAt indexPath: IndexPath)->UITableViewCell {
            let cell = tableView.dequeueReusableCell (withIdentifier: "cell", for: indexPath)
            cell.textLabel? .text = todos [indexPath.row] .task
            return cell
        }
    }