2016-05-21 8 views
4

From the docs verwende ich etwas ähnliches wie dynamisch eine Tabellenansicht auf Modelländerungen basierend aktualisieren:Mit Realm Sammlung Änderungsbenachrichtigungen in der Produktion

let results = realm.objects(Message).filter("someQuery == 'something'").sorted("timeStamp", ascending: true) 

// Observe Results Notifications 
notificationToken = results.addNotificationBlock { [weak self] (changes: RealmCollectionChange) in 
    guard let tableView = self?.tableView else { return } 
    switch changes { 
    case .Initial: 
    // Results are now populated and can be accessed without blocking the UI 
    tableView.reloadData() 
    break 
    case .Update(_, let deletions, let insertions, let modifications): 
    // Query results have changed, so apply them to the UITableView 
    tableView.beginUpdates() 
    tableView.insertRowsAtIndexPaths(insertions.map { NSIndexPath(forRow: $0, inSection: 0) }, 
     withRowAnimation: .Automatic) 
    tableView.deleteRowsAtIndexPaths(deletions.map { NSIndexPath(forRow: $0, inSection: 0) }, 
     withRowAnimation: .Automatic) 
    tableView.reloadRowsAtIndexPaths(modifications.map { NSIndexPath(forRow: $0, inSection: 0) }, 
     withRowAnimation: .Automatic) 
    tableView.endUpdates() 
    break 
    case .Error(let error): 
    // An error occurred while opening the Realm file on the background worker thread 
    fatalError("\(error)") 
    break 
    } 
} 

Die docs nicht tatsächliches Detail, wie die Datenquelle Delegierten der Tabelle erhalten diese geänderten Daten so dass ich eine Eigenschaft mit einem benutzerdefinierten Getter dachte tun würde:

var rows: Results<Message> { 
    let realm = try! Realm() 
    return result = realm.objects(Message).filter("someQuery == 'something'").sorted("timeStamp", ascending: true) 
} 

das funktioniert in der Praxis gut, aber der Kommentar Results are now populated and can be accessed without blocking the UI mich diesen Ansatz in Frage stellen. Sollte mein Getter ein leeres Array zurückgeben, bis die .Initial Benachrichtigung innerhalb des Benachrichtigungsblocks ausgelöst wurde, um sicherzustellen, dass der Hauptthread niemals blockiert wird?

Antwort

2

Es ist wahrscheinlich nicht offensichtlich aus dem Abschnitt Änderungsbenachrichtigungen der Dokumentation, aber es ist tatsächlich abgedeckt here in the docs.

Results Objekte sind aktive, automatisch aktualisierende Objekte. Wenn ihre Werte an anderer Stelle in der App (oder in einem Hintergrundthread) geändert werden, werden sie bei der nächsten Iteration der Laufschleife automatisch mit den neuen Werten aktualisiert (Vorbehalte. Results auf Hintergrundthreads müssen explizit aktualisiert werden).

Der Punkt der Änderungsbenachrichtigungen besteht darin, Ihnen lediglich mitzuteilen, dass eine Änderung aufgetreten ist, und beim nächsten Zugriff auf results sind die neuen Werte bereits vorhanden. So können Sie die Benutzeroberfläche entsprechend aktualisieren.

Also, Ihr extra Code ist nicht notwendig. Stellen Sie nur sicher, dass wenn ein Änderungsbenachrichtigungsblock ausgelöst wird, Sie immer noch auf dasselbe übergeordnete results Objekt verweisen, wenn Sie die Benutzeroberfläche aktualisieren, und es sollte einfach funktionieren ™. :)

+0

Durch zusätzlichen Code beziehen Sie sich auf meine Getter oder auf die Notwendigkeit, kein Ergebnis zurück, bis '.Initial' gefeuert hat? Danke für die Antwort, Realm ist großartig! –

+1

Ich habe festgestellt, dass die Docs den Code fest auf Null setzen, und die API scheint davon auszugehen, dass es auf der Datenebene kein Konzept von Abschnitten gibt. Ist es möglich, Abschnitte mit der neuen Realm-Filter- und Änderungsbenachrichtigungs-Unterstützung in irgendeiner Weise zu erreichen? – Marchy

+1

Das ist wirklich sehr hilfreich, weil das Dokument nicht offensichtlich ist. Danke Kumpel –