2017-02-02 2 views
0

コアデータストレージ内の既存のオブジェクトを編集しようとしています。ループを使わずに各オブジェクトの属性を編集すると、これは正常に動作しますが、ループを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; 

は、私がループで曲の属性を編集するために使用するコード(コード何とかのみ最後のオブジェクト(私の場合はsong3のパスを編集未満)、他のオブジェクトの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++)にを変更しようとしました。サイクルは、モデルに含まれる曲の数だけ何度も繰り返され、最後の曲のパスのみが変更されます。助けてよろしくお願いします。

P.S.ループ全体のコード:

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]); 
     } 
    } 
+0

forループのiterSongNameの値をチェックしていますか? –

+0

私はNSLogされたiterSong.nameとそれはループ内のすべての曲にとどまっています –

+0

ループバージョンの完全なコードを投稿できますか?あなたは実際にパスの値をいつ見ますか? – Dirk

答えて

0

問題は、この方法を解決しました。コードは同じループでうまく動作し始めました。また、mp3からwavにファイルを変換しました。しかし、ファイルにはその名前にハイフンを含めることができないため、問題が存在すると考えられます。

お返事ありがとうございました!

0

まず、私はあなたがNSManagedObjectContext performBlockメソッドの内部でそのループを実行すると仮定します。次に、オブジェクトを編集した後、NSManagedObjectsコンテキストにsave your changesが必要です。

のObjective-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)") 
    } 
+0

'performBlock:'メソッド内でループを使用しようとしましたが、変更した直後にコンテキストを保存しようとしました - これまでのところ、 'pathForResource:'メソッドは3曲目のパスしか見つけません。とにかくお返事ありがとう! –

+0

performBlockの内部で更新していないし、質問したときに保存していないので、アイテムの保存と更新の方法に問題があると推測します。私はそれがどこにあるか正確に100%ではない。それは調査に時間がかかる。しかし、あなたは私の答えで説明した方法をチェックする必要があります。これは、あなたのコンテキストの外で決してオブジェクトを編集して保存する必要がある方法です。 –

関連する問題