Swift、CoreData 和多对多关系:如何访问子项的顺序?

Posted

技术标签:

【中文标题】Swift、CoreData 和多对多关系:如何访问子项的顺序?【英文标题】:Swift, CoreData and many-to-many-relationship: how to access order of subitems? 【发布时间】:2021-01-30 20:05:36 【问题描述】:

我有以下关系:

播放列表可能包含一对多的歌曲,并且 歌曲可能属于一对多播放列表。

我的问题在于获取特定播放列表中歌曲的顺序 - 例如,

在播放列表 1 中,顺序可能是 3, 在播放列表 2 中,顺序可能为 1, 在播放列表 3 中,顺序可能是 5,等等。

此外,播放列表中歌曲的顺序可以更改,因为它们在表格视图中列出。

我现在想跟踪订单。

我尝试了以下方法:

    为 Song 实体创建一个新属性“PlaylistOrders” - 使用代表订单的 NSSet(播放列表的订单和 ManagedObjectId), 创建一个名为“PlaylistOrders”的新实体并将其连接到“Song”。此新实体还包含一个可转换的 objectId (ManagedObjectId)。

这两种方法似乎都非常容易出错 - 此外,我经常收到警告,例如“'NSKeyedUnarchiveFromData' 不应用于取消归档,将在未来的版本中删除”。

有没有更好、更复杂的方法在不同的播放列表中存储和检索歌曲的顺序?

【问题讨论】:

一个播放列表可能包含许多歌曲 - 因此:在这种情况下,我应该在播放列表中存储多个订单,代表歌曲 1 ...歌曲 n - 对我来说,这没有意义。或者我拿一本字典——但正如我上面提到的,这会引起很多麻烦 【参考方案1】:

在数据模型中Playlist 实体的songs 关系属性中,勾选“有序”复选框。届时,它们将以NSOrderedSet 的形式提供,而不是NSSet

【讨论】:

好的,我确实在数据模型中检查了“ordered” - 但出现的问题是:歌曲是根据什么标准排序的?时间戳、ID、订单号——还是其他什么?我想明确设置顺序,即取决于表视图中的行。我有一个表格视图,我可以拖放到其中 - 除了(在编辑模式下),我将更改歌曲的顺序 - 所以 CoreData 必须在 snyc 您通常如何使用NSArray?什么定义了元素的顺序?相同的答案适用于数据模型的有序关系中的顺序,即您将新歌曲添加到播放列表关系的顺序,或者您分配给关系的NSOrderedSet 中的顺序。 好的,我可以为 Song 设置一个新属性,即“ordeInPlaylist”。在这种情况下,我将只代表一个播放列表 - 但是一首歌曲在多个播放列表中以不同的顺序表示这一事实呢? 由于您提到歌曲可以与许多播放列表相关,因此尚不清楚该属性将应用于哪个播放列表。 这就是我推荐你使用“有序”关系的原因。关系中歌曲的顺序信息不会存储在歌曲实体本身中,您可以将不同位置的同一首歌曲添加到不同的播放列表中。【参考方案2】:

感谢 Eugene,它现在可以工作了 - 我的意思是使用 NSOrderedSet 的方法。

关于在 tableview 中重新排序歌曲项目的一个提示 - 以下代码 sn-p 显示了如何重新排列 NSOrderedSet 中的项目并将它们存储到 CoreData - 我们只需要一个 NSMutableOrderedSet:

func moveSongItemInPlaylist(playlist: Playlist, item: SongItem, fromOrder: Int, toOrder: Int) 
    
    let orderedSet = playlist.mutableOrderedSetValue(forKey: "songItems")
    
    let indices = IndexSet(integer: fromOrder)
    
    if (fromOrder > toOrder) 
        // we're moving up
        orderedSet.moveObjects(at: indices, to: toOrder)
     else 
        // we're moving down
        orderedSet.moveObjects(at: indices, to: toOrder - indices.count)
    
    
    do 
        try self.managedObjectContext.save()
     catch 
        print(error)
    

【讨论】:

以上是关于Swift、CoreData 和多对多关系:如何访问子项的顺序?的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中将 NSManagedObject 添加到 CoreData 多对多关系时防止循环

如何判断一对一对多和多对多的关系

iOS / iPhone CoreData 关系

如何在 DynamoDB 中建模一对一、一对多和多对多关系

从 CoreData 关系中获取错误实体的对象

CoreData:如何建模循环多对多关系