Ios 当领域上的对象失效时该怎么办

Ios 当领域上的对象失效时该怎么办,ios,swift,realm,Ios,Swift,Realm,在我的iOS应用程序中,我使用领域库存储数据。它工作得很好,直到出于某种原因,对象失效。 (在特定情况下,原因可能是我有时在视图中可视化的相同数据上实现后台作业,或者类似的场景) 我知道为什么会发生这种情况,我理解正确的行为,但从那以后:我应该实施什么样的正确行为 我很想再次从领域中提取数据并继续我的工作,但当一个对象失效时,每个字段都不可访问并使环境崩溃(因此,我不知道该对象的唯一+不变id是什么) 如何安全地再次从该对象提取当前数据,而不将id存储在ViewController中? 下面是一

在我的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()
      }
    }