【问题标题】:Sorting Realm results collection on computed property?对计算属性的领域结果集合进行排序?
【发布时间】:2019-07-08 16:14:32
【问题描述】:

我在我的 Swift iOS 应用程序中使用 Realm,并且我有一个模型,我正在尝试向其中添加计算属性。下面是这个类的样子:

class Conversation: Object {

    @objc dynamic var conversationId: String = generateConversationId()
    @objc dynamic var createdTime = Date()
    @objc dynamic var title: String = ""
    let messages = List<Message>()

    var lastUpdated: Date {
        if let newestMessage = self.messages.sorted(byKeyPath: "timestamp", ascending: false).first {
            return newestMessage.timestamp
        } else {
            return Date(timeIntervalSince1970: 0)
        }
    }        
}

如您所见,此对象表示一个会话,该会话具有多个属性,其中一个是属于该会话的消息列表。我添加的计算属性 (lastUpdated) 应该只返回 messages 列表中最新消息的时间戳,或者,当列表为空时,它将返回默认日期值。

在我的一个视图控制器中,我正在创建一个结果集合来访问 Conversation 对象,如下所示:

var conversations: Results<Conversation> = realm.objects(Conversation.self)

这可行,我可以按预期访问每个 Conversation 上的 lastUpdated 属性。但是,我想让这个集合按lastUpdated 属性排序,所以我尝试像这样修改我的结果集合:

var conversations: Results<Conversation> = realm.objects(Conversation.self).sorted(byKeyPath: "lastUpdated", ascending: true)

当我这样做时,应用程序会抛出以下异常:

Terminating app due to uncaught exception 'RLMException', reason: 'Cannot sort on key path 'lastUpdated': property 'Conversation.lastUpdated' does not exist.'

认为这可能会发生,因为 lastUpdated 计算属性未保留在 Conversation 对象上(我将使用 Realm Studio 快速验证这一点,但我的 Realm 已加密)。我没有明确地忽略这个属性,但我认为是这种情况,因为lastUpdated 不像我的所有其他属性那样用@objc dynamic 装饰。我尝试添加它,擦除我的应用安装,重新编译并再次测试,但我仍然遇到同样的异常。

也许不可能持久化一个计算属性(因为,嗯,它是计算出来的!)但是有没有其他方法可以指定我的对话结果集合应该按这个属性排序?

【问题讨论】:

    标签: ios swift realm computed-properties


    【解决方案1】:

    正如您所怀疑的,您不能持久化计算属性,Realmsorted(byKeyPath:,ascending:) 方法仅适用于持久化属性。在保持自动更新Results 的同时,无法根据计算属性对Results 实例进行排序。

    但是,如果您不需要 Results 的自动更新特性,可以使用一种解决方法。你可以使用 Swift 的sorted 方法,它接受一个闭包作为它的排序参数,这将产生一个[Conversation] 类型的返回值:

    let conversations = realm.objects(Conversation.self).sorted(by: {$0.lastUpdated < $1.lastUpdated})
    

    【讨论】:

    • 感谢您的快速回复!不幸的是,我确实需要结果的自动更新方面(我还使用通知令牌来观察更改并相应地更新 UITableView)。
    • @bmt22033 那你为什么接受这个答案?我也遇到了同样的问题,请问您找到其他解决方案了吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    相关资源
    最近更新 更多