2015-11-20 55 views
1

假设我有一个名为Playlist的NSManagedObject子类。这个Playlist对象与另一个名为Song的NSManagedObject子类具有多对多关系。假设我的Playlist对象在关系中有一首与歌曲“歌曲A”相关联的歌曲。核心数据为多对多关系添加相同的对象

考虑到这个例子,我试图再次向关系中添加“歌曲A”,la将两首歌曲添加到播放列表中。

下面是用于添加对象到关系码:

- (void)addSongsObject:(Song *)theSong { 
    NSMutableOrderedSet *song = [self mutableOrderedSetValueForKey:@"songs"]; 
    [mutableSongs addObject:theSong]; 
} 

哪里self是播放列表对象。由于关系中已有特定歌曲的实例,因此不会添加另一个实例。

什么是最好的方式去做这个与核心数据?

+1

也许做一个名为“SongOccurrence”的中间包装对象。这些在列表中也是独一无二的,但其中两个可能引用相同(独特的)歌曲。 –

+1

@NicolasMiari你应该做出答案而不是评论。这真的是唯一体面的解决方案。 –

+0

我刚刚做到了;抱歉。我在我的iPhone上随便浏览,因此不想输入完整的答案。 –

回答

2

就像我在我的评论中提到的,解决方法是在层次结构中插入一个中间容器对象,以表示播放列表中给定歌曲的每个(唯一)出现;我们称之为SongOccurrenceSongInstance也会这样)。

由于核心数据中的多对一关系使用NSSet(它是无序的,但要求每个元素最多出现一次,与NSArray不同)建模,因此无法将歌曲的同一个实例添加两次或更多次。

所以,这SongOccurrence对象有向(唯一的)Song它所代表的引用(以及存储在其他地方,唯一-say,Library),并可能代表了其在播放列表顺序的index属性。

可以使用表示对象的唯一ID的字符串或int属性来建模“参考”(使用关系也需要设置相反的关系)。由于给定歌曲可能属于多个播放列表,所以它必须是“一对多”)。

当播放列表中,您只需在设置中SongOccurrence情况下通过他们的index排序,检索每个Song“有效载荷”,并播放一前一后。

+0

我不是核心数据专家,但如果您发现任何错误或不准确之处,请告知我们。 –

+0

感谢您的回复!我会看看这个。 – hgwhittle

+1

个人而言,我认为值得将SongOccurrence-Song建模为一种关系,并用一对多的反转法进行建模是值得的:如果没有别的办法,它就避免了必须创建一个唯一的ID,并且在删除一首歌时帮助保持参照完整性。 – pbasdf