Realm Swift 如何在结果更新时得到通知
Realm Swift How to get notified when Result has been updated
我正在使用 Realm 结果对象 Result<AnObject>
作为 uitableview
的数据源。在加载更多 AnObject
对象的不同视图控制器中有一些延迟 API 调用。我想要的是在更新我的数据源以更新 table 视图时收到通知。
我做了一些搜索,知道我需要使用 KVO,但我找不到任何示例来说明如何将它与 realm.My 一起使用,代码如下所示:
class myViewController: UIViewController, UITableViewDatasource {
let realm = try! Realm()
override func viewDidLoad() {
super.ViewDidLoad()
var datasource = realm.objects(AnObject.self)
// I need to some how observe the change of datasource
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return datasource.count
}
...
}
更新
我尝试在它工作之前使用 realm.addNotificationBlock
(与@joern 回答中的方式相同),但问题是当任何领域对象不仅更新数据源类型时,块将 运行。这会重新加载 table 太多不必要的时间。
更新 2
我的应用程序有一个 CalendarViewController,它在上半部分包含一个 FSCalenar 视图,在下半部分包含一个链接到 EventsViewController 的容器,其中包含事件的 table 视图。
我有那么长的时间从API 得到这么多事件。所以我给 API 打了大约 20 次电话,他们每个人都得到了一些事件。并在 NSOperationQueue
中添加所有调用操作,然后根据我需要首先加载的内容设置操作优先级。因此每个 API 调用在完成时更新数据源对象。我需要事件 tableview 来重新加载。
API 调用发生在已被 CalendarViewController
调用的 APIManager class 方法中
您不必使用 KVO。您可以使用 Realm 的通知功能:
Realm instances send out notifications to other instances on other
threads every time a write transaction is committed. These
notifications can be observed by registering a block:
let token = realm.addNotificationBlock { notification, realm in
let realm = try! Realm()
self.datasource = realm.objects(AnObject.self)
self.tableView.reloadData()
}
只要您保持对此令牌的强引用,您就会收到通知。
更新:
如果您不想使用 Realm 的通知,您可以 post 每当 API 调用 returns 结果时您拥有通知,然后相应地重新加载您的 table 视图:
将您的 EventViewController
添加到默认 NSNotificationCenter
并添加一个操作:
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("didReceiveReloadNotification:"), name: "RELOAD_NOTIFICATION", object: nil)
...
}
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
func didReceiveReloadNotification(notification: NSNotification) {
let realm = try! Realm()
datasource = realm.objects(AnObject.self)
tableView.reloadData()
}
然后每当您的 API 请求操作之一完成时 post 通知:
dispatch_async(dispatch_get_main_queue()) { () -> Void in
NSNotificationCenter.defaultCenter().postNotificationName("RELOAD_NOTIFICATION", object: nil)
}
我在这里更新 Swift 4+ 的答案以获得结果更新通知
第 1 点:声明以下属性
var notificationToken: NotificationToken? = nil
let results = realmManager.realm.objects(MemberHistory.self)
第 2 点:您可以在 viewWillAppear 上添加以下部分,也可以添加一个方法并在 ViewWillAppear 上调用该方法
{
notificationToken = results?.observe {(changes: RealmCollectionChange) in
switch changes {
case .initial(let data):
print("initials count - \(data.count)")
self.chatTableView.reloadData()
case .update(_, let deletions, let insertions, let modifications):
if(insertions.count == self.arrMessages?.count)
{
//This section will execute when the user's first load of messages comes from API, I had used this for my internal purpose
}
else
{
self.chatTableView.beginUpdates()
self.chatTableView.insertRows(at: insertions.map({ IndexPath(row: [=11=], section: 0) }),
with: .none)
self.chatTableView.reloadRows(at: modifications.map({ IndexPath(row: [=11=], section: 0) }), with: .none)
self.chatTableView.deleteRows(at: deletions.map({ IndexPath(row: [=11=], section: 0)}),
with: .none)
self.chatTableView.endUpdates()
self.chatTableView.scrollToBottom()
}
case .error(let error):
Toast(text: "Error", duration: Delay.short).show()
fatalError("\(error)")
}
}
}
我正在使用 Realm 结果对象 Result<AnObject>
作为 uitableview
的数据源。在加载更多 AnObject
对象的不同视图控制器中有一些延迟 API 调用。我想要的是在更新我的数据源以更新 table 视图时收到通知。
我做了一些搜索,知道我需要使用 KVO,但我找不到任何示例来说明如何将它与 realm.My 一起使用,代码如下所示:
class myViewController: UIViewController, UITableViewDatasource {
let realm = try! Realm()
override func viewDidLoad() {
super.ViewDidLoad()
var datasource = realm.objects(AnObject.self)
// I need to some how observe the change of datasource
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return datasource.count
}
...
}
更新
我尝试在它工作之前使用 realm.addNotificationBlock
(与@joern 回答中的方式相同),但问题是当任何领域对象不仅更新数据源类型时,块将 运行。这会重新加载 table 太多不必要的时间。
更新 2
我的应用程序有一个 CalendarViewController,它在上半部分包含一个 FSCalenar 视图,在下半部分包含一个链接到 EventsViewController 的容器,其中包含事件的 table 视图。
我有那么长的时间从API 得到这么多事件。所以我给 API 打了大约 20 次电话,他们每个人都得到了一些事件。并在 NSOperationQueue
中添加所有调用操作,然后根据我需要首先加载的内容设置操作优先级。因此每个 API 调用在完成时更新数据源对象。我需要事件 tableview 来重新加载。
API 调用发生在已被 CalendarViewController
您不必使用 KVO。您可以使用 Realm 的通知功能:
Realm instances send out notifications to other instances on other threads every time a write transaction is committed. These notifications can be observed by registering a block:
let token = realm.addNotificationBlock { notification, realm in
let realm = try! Realm()
self.datasource = realm.objects(AnObject.self)
self.tableView.reloadData()
}
只要您保持对此令牌的强引用,您就会收到通知。
更新:
如果您不想使用 Realm 的通知,您可以 post 每当 API 调用 returns 结果时您拥有通知,然后相应地重新加载您的 table 视图:
将您的 EventViewController
添加到默认 NSNotificationCenter
并添加一个操作:
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("didReceiveReloadNotification:"), name: "RELOAD_NOTIFICATION", object: nil)
...
}
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
func didReceiveReloadNotification(notification: NSNotification) {
let realm = try! Realm()
datasource = realm.objects(AnObject.self)
tableView.reloadData()
}
然后每当您的 API 请求操作之一完成时 post 通知:
dispatch_async(dispatch_get_main_queue()) { () -> Void in
NSNotificationCenter.defaultCenter().postNotificationName("RELOAD_NOTIFICATION", object: nil)
}
我在这里更新 Swift 4+ 的答案以获得结果更新通知
第 1 点:声明以下属性
var notificationToken: NotificationToken? = nil
let results = realmManager.realm.objects(MemberHistory.self)
第 2 点:您可以在 viewWillAppear 上添加以下部分,也可以添加一个方法并在 ViewWillAppear 上调用该方法
{
notificationToken = results?.observe {(changes: RealmCollectionChange) in
switch changes {
case .initial(let data):
print("initials count - \(data.count)")
self.chatTableView.reloadData()
case .update(_, let deletions, let insertions, let modifications):
if(insertions.count == self.arrMessages?.count)
{
//This section will execute when the user's first load of messages comes from API, I had used this for my internal purpose
}
else
{
self.chatTableView.beginUpdates()
self.chatTableView.insertRows(at: insertions.map({ IndexPath(row: [=11=], section: 0) }),
with: .none)
self.chatTableView.reloadRows(at: modifications.map({ IndexPath(row: [=11=], section: 0) }), with: .none)
self.chatTableView.deleteRows(at: deletions.map({ IndexPath(row: [=11=], section: 0)}),
with: .none)
self.chatTableView.endUpdates()
self.chatTableView.scrollToBottom()
}
case .error(let error):
Toast(text: "Error", duration: Delay.short).show()
fatalError("\(error)")
}
}
}