gpt4 book ai didi

ios - 当 Realm 上的对象失效时该怎么办

转载 作者:行者123 更新时间:2023-11-28 11:27:45 25 4
gpt4 key购买 nike

在我的 iOS 应用程序中,我使用 Realm 库来存储数据。它工作得很好,直到出于某种原因,对象失效。(特定情况下的原因可能是我有时会在 View 或类似场景中可视化的相同数据上执行后台作业)。

我知道为什么会这样,我知道这是正确的行为,但从那时起:我应该实现的正确行为是什么?

我很想再次从 Realm 中提取数据并继续我的工作,但是当一个对象失效时,每个字段都无法访问并且使环境崩溃(所以,我不知道什么是唯一+不可变的 id对象)。

如何在不将 id 存储在 ViewController 中的情况下再次安全地从该对象中提取当前数据?

这是一些代码。由于应用程序的结构不同,我不得不对其进行大量编辑,但问题仍然存在。假设 TableView 代表的是 View 并且所有技术细节都在那里。

// 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
}

最佳答案

问题

据我了解,您希望在对象失效时访问对象的属性。如果我错了请纠正我:)

首先,让我们来看看isInvalidated属性

Indicates if the object can no longer be accessed because it is now invalid.

An object can no longer be accessed if the object has been deleted from the Realm that manages it, or if invalidate() is called on that Realm.

这意味着一个对象只有在被 Realm 管理时才能失效。

我的解决方案

从管理它的 Realm 中分离对象。如果对象不受任何 Realm 管理,当然它永远不会失效,您可以根据需要访问属性。

怎么做

每当您从 Realm 获取对象时,将其分离(创建一个克隆对象)。

  1. 将以下代码添加到您的项目中。它用于分离 Result 中的每个对象从 Realm 获取后。我找到了 here

    protocol DetachableObject: AnyObject {
    func detached() -> Self
    }

    extension Object: DetachableObject {

    func detached() -> Self {
    let detached = type(of: self).init()
    for property in objectSchema.properties {
    guard let value = value(forKey: property.name) else { continue }

    if property.isArray == true {
    //Realm List property support
    let detachable = value as? DetachableObject
    detached.setValue(detachable?.detached(), forKey: property.name)
    } else if property.type == .object {
    //Realm Object property support
    let detachable = value as? DetachableObject
    detached.setValue(detachable?.detached(), forKey: property.name)
    } else {
    detached.setValue(value, forKey: property.name)
    }
    }
    return detached
    }
    }

    extension List: DetachableObject {
    func detached() -> List<Element> {
    let result = List<Element>()

    forEach {
    if let detachable = $0 as? DetachableObject {
    let detached = detachable.detached() as! Element
    result.append(detached)
    } else {
    result.append($0) //Primtives are pass by value; don't need to recreate
    }
    }

    return result
    }

    func toArray() -> [Element] {
    return Array(self.detached())
    }
    }

    extension Results {
    func toArray() -> [Element] {
    let result = List<Element>()

    forEach {
    result.append($0)
    }

    return Array(result.detached())
    }
    }
  2. 而不是保留 events作为RLMResults<RLMMyEvent> , 保留为 [RLMMyEvent] .

  3. 获取结果后,分离对象并转换为数组

    events = RLMMyEvent.objects(with: predicate).toArray()

现在您可以访问属性而不必担心无效的对象和崩溃。

请注意,如果 Realm 中的原始对象或其值发生更改,分离的对象将不会更新。

关于ios - 当 Realm 上的对象失效时该怎么办,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57673739/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com