【问题标题】:Magical Record, CoreData, deleting a record and renumberingMagical Record,CoreData,删除一条记录并重新编号
【发布时间】: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
    }

}

【问题讨论】:

    标签: objective-c regex core-data predicate magicalrecord


    【解决方案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 和删除项目。它们已经存在了很长时间并且有解决方法,但苹果似乎还没有修复:stackoverflow.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];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-04
      • 1970-01-01
      • 2013-08-02
      • 1970-01-01
      • 2012-10-24
      • 1970-01-01
      • 2016-10-07
      • 1970-01-01
      相关资源
      最近更新 更多