Ios 当领域上的对象失效时该怎么办
在我的iOS应用程序中,我使用领域库存储数据。它工作得很好,直到出于某种原因,对象失效。 (在特定情况下,原因可能是我有时在视图中可视化的相同数据上实现后台作业,或者类似的场景) 我知道为什么会发生这种情况,我理解正确的行为,但从那以后:我应该实施什么样的正确行为 我很想再次从领域中提取数据并继续我的工作,但当一个对象失效时,每个字段都不可访问并使环境崩溃(因此,我不知道该对象的唯一+不变id是什么) 如何安全地再次从该对象提取当前数据,而不将id存储在ViewController中? 下面是一些代码。由于应用程序的结构不同,我不得不对其进行大量编辑,但问题仍然存在。假设表视图委托是视图,所有技术细节都在那里Ios 当领域上的对象失效时该怎么办,ios,swift,realm,Ios,Swift,Realm,在我的iOS应用程序中,我使用领域库存储数据。它工作得很好,直到出于某种原因,对象失效。 (在特定情况下,原因可能是我有时在视图中可视化的相同数据上实现后台作业,或者类似的场景) 我知道为什么会发生这种情况,我理解正确的行为,但从那以后:我应该实施什么样的正确行为 我很想再次从领域中提取数据并继续我的工作,但当一个对象失效时,每个字段都不可访问并使环境崩溃(因此,我不知道该对象的唯一+不变id是什么) 如何安全地再次从该对象提取当前数据,而不将id存储在ViewController中? 下面是一
// A class variable
var events: RLMResults<RLMMyEvent>
// A table view that shows all "MyEvents"
var tableview: UITableView
func initialiseView(_ predicate: NSPredicate) {
// Get the events with a predicate from Realm
events = RLMMyEvent.objects(with: predicate)
tableview.reloadData()
}
// All tableView delegates, and in particular
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! MyCell
let event = self.events[UInt(indexPath.row)]
if !event.isInvalidated {
} else {
/***** HERE is the problem. What to do here?
HOW to get those data again, since I cannot
get that event's unique ID? ****/
}
cell.initialize(event)
return cell
}
//类变量
var事件:RLMResults
//显示所有“MyEvents”的表视图
var tableview:UITableView
func initialiseView(\谓词:NSPredicate){
//从领域获取带有谓词的事件
events=RLMMyEvent.objects(带:谓词)
tableview.reloadData()
}
//所有tableView代理,尤其是
func tableView(tableView:UITableView,cellForRowAt indexath:indexPath)->UITableViewCell{
让cell=tableView.dequeueReusableCell(标识符为:reuseIdentifier,for:indexPath)作为!MyCell
让event=self.events[UInt(indexPath.row)]
如果!event.isInvalidated{
}否则{
/*****问题出在这里,怎么办?
如何再次获取这些数据,因为我无法
获取该事件的唯一ID****/
}
单元格初始化(事件)
返回单元
}
在访问对象之前,是否尝试使用RealmObject.isInvalidated
变量检查对象是否仍然有效?使用此密钥不会导致您遇到的崩溃
当前情景
realmObject.stringArray.append("")
建议的方法
if !realmObject.isInvalidated {
realmObject.stringArray.append("")
}
问题
据我所知,当对象无效时,您希望访问对象的属性。如果我错了,请纠正我:)
首先,让我们看看房地产
指示是否由于对象现在无效而无法再访问该对象
如果对象已从管理该对象的领域中删除,或者在该领域中调用了invalidate(),则无法再访问该对象
这意味着一个对象只有在由领域管理时才能失效
我的解决方案
将对象与管理它的领域分离。若对象不由任何领域管理,那个么它当然永远不会失效,并且您可以根据需要访问属性
如何做
无论何时从领域获取对象,都要分离它(创建克隆对象)
Result
中的每个对象。我发现
请注意,如果域中的原始对象或其值发生更改,则分离的对象将不会更新。作为解决方案,您可以观察
事件
数组中的更改,并相应地更新/删除单元格,如
eventsObserveToken = events.observe { [weak tableView] changes in
guard let tableView = tableView else { return }
switch changes {
case .initial:
tableView.reloadData()
case .update(_, let deletions, let insertions, let updates):
tableView.applyChanges(deletions: deletions, insertions: insertions, updates: updates)
case .error: break
}
}
和一个扩展
extension IndexPath {
static func fromRow(_ row: Int) -> IndexPath {
return IndexPath(row: row, section: 0)
}
}
extension UITableView {
func applyChanges(deletions: [Int], insertions: [Int], updates: [Int]) {
beginUpdates()
deleteRows(at: deletions.map(IndexPath.fromRow), with: .automatic)
insertRows(at: insertions.map(IndexPath.fromRow), with: .automatic)
reloadRows(at: updates.map(IndexPath.fromRow), with: .automatic)
endUpdates()
}
}
我相信当一个对象失效时,它将从结果数组中删除,这样你的应用程序就不会崩溃
或者,您可以使用。Unrealm使您能够轻松地将Swift本机类、结构和枚举存储到域中,而无需费劲。而且你根本不需要担心无效对象,因为即使你试图访问无效对象,你的应用程序也不会崩溃。此外,如果您尝试从其他线程访问对象,您的应用程序也不会崩溃
添加示例代码,以便我们能够更准确地帮助您。谢谢,我这样做了。我使用了
IsInvalidated
,但我的问题是如何再次安全地从该对象中提取数据?
IsInvalidated
只是避免了崩溃,但是我必须再次提取数据。我认为这可能是一个很好的通用解决方案。我会尽快实施,并让你知道。非常感谢你!这是一个很好的建议。在每一个发生碰撞的地方放置一个观察者可能是最干净的解决方案。实现Unrealm有点太晚了,我将不得不改变项目中相当大的一部分。我想知道为什么Realm不把这种行为作为一种选择。@SimoneChelo事实上,切换从来都不晚。您需要做的唯一修改是遵守Realmable协议,而不是从对象类继承,并删除@objc dynamic
关键字。Unrealm也适用于类。
eventsObserveToken = events.observe { [weak tableView] changes in
guard let tableView = tableView else { return }
switch changes {
case .initial:
tableView.reloadData()
case .update(_, let deletions, let insertions, let updates):
tableView.applyChanges(deletions: deletions, insertions: insertions, updates: updates)
case .error: break
}
}
extension IndexPath {
static func fromRow(_ row: Int) -> IndexPath {
return IndexPath(row: row, section: 0)
}
}
extension UITableView {
func applyChanges(deletions: [Int], insertions: [Int], updates: [Int]) {
beginUpdates()
deleteRows(at: deletions.map(IndexPath.fromRow), with: .automatic)
insertRows(at: insertions.map(IndexPath.fromRow), with: .automatic)
reloadRows(at: updates.map(IndexPath.fromRow), with: .automatic)
endUpdates()
}
}