Magical Record,CoreData,删除一条记录并重新编号

Posted

技术标签:

【中文标题】Magical Record,CoreData,删除一条记录并重新编号【英文标题】:Magical Record, CoreData, deleting a record and renumbering 【发布时间】:2013-08-05 22:50:39 【问题描述】:

我正在添加从播放列表中删除歌曲 (playlistTrack) 的功能。每个 playlistTrack 都有一个与之关联的 playlist_track_number,因此我们知道歌曲的播放顺序。因此,在删除 playlistTrack 后,我需要分配新的 playlist_track_number 后面的所有 playlistTrack,即比之前的 playlist_track_number 少 1。

我的代码在这里运行良好一次,然后崩溃,控制台显示“'无法对对象 3 进行正则表达式匹配”。有什么帮助吗?

NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];


NSPredicate *predicateList = [NSPredicate predicateWithFormat:@"(playlist.name CONTAINS[cd] %@)", activePlaylistString];

NSArray *newArray = [[NSArray alloc]init];
newArray = (NSArray*)[Playlist_Track MR_findAllWithPredicate:predicateList];

for (int i = (delTrack + 1); i <= [newArray count]; i++) 

    localContext = [NSManagedObjectContext MR_contextForCurrentThread];

    NSString *nextTrackNumberString = [NSString stringWithFormat:@"%i",i];

    NSPredicate *nextPredicate = [NSPredicate predicateWithFormat:@"(playlist.name CONTAINS[cd] %@) AND (playlist_track_number MATCHES [cd] %@)", activePlaylistString, nextTrackNumberString];

    nextTrack = [Playlist_Track MR_findFirstWithPredicate:nextPredicate inContext:localContext];

    if (nextTrack) 

        int j = i-1;

        nextTrack.playlist_track_numberValue = j;

        [localContext MR_saveToPersistentStoreWithCompletion:nil];
    

    if (!nextTrack) 
        //Do Nothing
    


【问题讨论】:

【参考方案1】:

与其进行大量不同的获取,只需进行一次获取即可获取所有需要更新的对象,然后遍历它们并执行更新。根据项目的数量,您可以批量处理来自 fetch 的响应或将项目作为故障返回,然后批量保存。

【讨论】:

您认为这实际上是导致问题的原因还是只是作为最佳实践的建议?【参考方案2】:

此错误表明您尝试将“NSPredicate”与不适当的类型一起使用 (playlist_track_number MATCHES [cd] %@) 我想您正在尝试使用字符串匹配号码playlist_track_number

顺便说一句,我想您的 CoreData 中的架构不是很有效。 此删除操作将花费很长时间 (在循环中查找并获取多于多个查找一个) 此外,您当前的架构不允许在 2 个或更多播放列表中使用一个 playlistTrack 所以最好从 playlistTrack 中删除 playlist_track_number 属性

要从播放列表中快速插入和删除,您可以使用链表双向链表结构。当每个 playlistTrack 项目将与下一个(和上一个)项目有关系时。 在播放列表实体中,您只能与头(和尾)项目建立关系,也可以拥有 count 属性。

您还可以在 CoreData 中使用NSOrderedSet 建立一对多关系 这将允许您在索引处插入项目在索引处删除项目 (但它目前有很多未解决的错误)

这两种变体都允许您在没有playlist_track_number 属性的情况下拥有轨道编号/订单

【讨论】:

感谢您的建议,但似乎有很多未解决的错误与 NSOrderedSet 和删除项目。它们已经存在了很长时间并且有解决方法,但苹果似乎还没有修复:***.com/questions/7385439/… 确实如此。我们仍在等待苹果的修复。【参考方案3】:

根据 Flop 的建议,我对代码进行了如下修改。这被硬编码为始终删除索引 3 处的轨道,但可以通过将参数传递给方法来轻松更改。

NSArray *trackList = [[NSArray alloc]init];

NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];

Playlist *selectedPlaylist;

selectedPlaylist = [Playlist MR_findFirstByAttribute:@"name" withValue:activePlaylistString];

trackList = (NSArray*)selectedPlaylist.playlist_trackSet;

NSMutableArray *newArray = [trackList mutableCopy];

NSUInteger delIndex = 3;

[newArray removeObjectAtIndex:delIndex];

trackList = newArray;

NSOrderedSet *trackSet = (NSOrderedSet*)trackList;

selectedPlaylist.playlist_track = trackSet;

[localContext MR_saveToPersistentStoreWithCompletion:nil];

【讨论】:

以上是关于Magical Record,CoreData,删除一条记录并重新编号的主要内容,如果未能解决你的问题,请参考以下文章

Magical Record,CoreData,删除一条记录并重新编号

使用 Magical Record 将对象数组插入 Core Data

导入与 Core Data 和 Magical Record 的关系

如何在 Core Data 和 Magical Record 中存储一系列电子邮件

使用 Kiwi、Core Data 和 Magical Record 进行单元测试

Plain Core Data vs Core Data + Magical Record