【问题标题】:edit core data model objects in a loop循环编辑核心数据模型对象
【发布时间】:2017-02-02 11:54:41
【问题描述】:

我正在尝试编辑 Core Data 存储中的现有对象。当我在没有循环的情况下编辑每个对象的属性时,这工作正常,但是当我尝试在for 循环中执行此操作时,只有我的最后一个对象获得新属性。 这是我用来在没有循环的情况下编辑对象的代码。此代码工作正常):

NSFetchRequest *songsRefreshRequest = [[NSFetchRequest alloc] initWithEntityName:@"Music"];
songsRefreshRequest.predicate = nil;
songsRefreshRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"name"
                                                                      ascending:YES
                                                                       selector:@selector(localizedStandardCompare:)]];
NSError *frError;
NSArray *fetchedSongs = [self.context executeFetchRequest:songsRefreshRequest error:&frError];
fetchedSongs ? : NSLog(@"Error in fetch while refreshing songs: %@", [frError localizedDescription]);


NSString *song1path = [[NSBundle mainBundle] pathForResource:@"Beautiful-birds-song-in-the-morning" ofType:@"mp3"];
NSString *song2path = [[NSBundle mainBundle] pathForResource:@"Birds-singing-relaxation" ofType:@"mp3"];
NSString *song3path = [[NSBundle mainBundle] pathForResource:@"Morning Melody" ofType:@"mp3"];

Music *song1 = (Music *) [fetchedSongs objectAtIndex:0];
Music *song2 = (Music *) [fetchedSongs objectAtIndex:1];
Music *song3 = (Music *) [fetchedSongs objectAtIndex:2];

song1.name = @"Beautiful-birds-song-in-the-morning";
song2.name = @"Birds-singing-relaxation";
song3.name = @"Morning Melody";

song1.path = song1path;
song2.path = song2path;
song3.path = song3path;

这是我用来在循环中编辑歌曲属性的代码(下面的代码以某种方式仅编辑最后一个对象(在我的情况下为歌曲 3)的路径,其他对象的 path 属性变为 NULL。我可以'不知道为什么):

for (Music *iterSong in fetchedSongs){
    NSString *iterSongName = [iterSong valueForKey:@"name"];
    iterSong.path = [[NSBundle mainBundle] pathForResource: iterSongName ofType:@"mp3"];
}

我已经尝试将 for each 更改为 for (int i=0; i<[fetchedSongs count]; i++) 这没有帮助。 Cycle 重复与模型中的歌曲一样多的次数,并且只会更改最后一首歌曲的路径。感谢任何帮助,在此先感谢!

附:整个循环代码:

for (Music *iterSong in fetchedSongs){
        //Music *iterSong = (Music*) [fetchedSongs objectAtIndex:i];
        NSLog(@"inerSong.name = %@", iterSong.name);
        NSLog(@"inerSong.oldPath = %@", iterSong.path);

        NSString *iterSongName = [iterSong valueForKey:@"name"];
        NSString *iterSongPath = [[NSBundle mainBundle] pathForResource: iterSongName ofType:@"mp3"];
        NSLog(@"iterSongPath (string) = %@", iterSongPath);
        iterSong.path = iterSongPath;
        NSLog(@"iterSong.newPath = %@", iterSong.path);

    }

    if ([self.context hasChanges]){
        NSError *error;
        if (![self.context save:&error]){
            NSLog(@"error while saving context after refreshing song paths: %@", [error localizedDescription]);
        }
    }

【问题讨论】:

  • 你检查 for 循环中 iterSongName 的值吗?
  • 我 NSLog'ed iterSong.name 并且它对循环中的每一首歌都保持正确
  • 你能发布循环版本的完整代码吗?你什么时候真正寻找路径值?
  • @Dirk I NSLog 循环内的路径值。而且它们不会出现在循环之外,因为我使用这些路径的 AVAudioPlayer 仅适用于最后一首歌曲。我将整个循环代码添加到问题中。
  • 我不认为这是循环或核心数据的问题,但我仍然不知道出了什么问题。如果您设置 song1.name 等,然后使用这些名称(不在循环中)询问路径,会发生什么?

标签: ios objective-c xcode core-data


【解决方案1】:

首先,我假设您在 NSManagedObjectContext performBlock 方法中运行该循环。其次,您需要在编辑对象后将save your changes 发送到您的 NSManagedObjects 上下文。

目标-C:

NSError *error = nil;
if ([[self managedObjectContext] save:&error] == NO) {
    NSAssert(NO, @"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]);
}

斯威夫特:

do {

        try managedObjectContext.save()
    } catch {
        fatalError("Failure to save context: \(error)")
    }

【讨论】:

  • 尝试在 performBlock: 方法中使用循环并尝试在进行更改后立即保存上下文 - 到目前为止没有运气,仍然 pathForResource: 方法仅找到第三首歌曲的路径。还是谢谢你的回答!
  • 由于您没有在 performBlock 内部进行更新,并且在您提出问题时也没有保存,我猜您的保存和更新项目的方法有问题。我不是 100% 准确地知道它在哪里,但需要时间来调查。但是您需要检查我在回答中描述的方法,这是您应该如何编辑和保存对象,永远不要超出您的上下文。
【解决方案2】:

问题以这种方式解决: 我从文件名中删除了所有连字符。并且代码开始在相同的循环中正常工作。我还将文件从 mp3 转换为 wav。但我认为存在这个问题是因为文件的名称中不能包含连字符。

感谢所有回答的人!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-08
    • 2011-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多