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 中存储一系列电子邮件