2012-02-28 10 views
9

コアデータのNSOrderedSet関係のオブジェクトの順序で変更を保存できない理由を知っている人はいますか? NSOrderedSet関係で生成された関数を使うのがうまくいかず、私は常にkeypathを使います。以下は、テーブルビュー内の2つの関数のコードです。コアデータのNSOrderedSet関係を並べ替えることができません

tableView:moveRowAtIndexPath:toIndexPath:は正常に保存すると主張していますが、変更は実際には保存されません。つまり、[tableView reloadData];を実行すると、古い注文はそのまま残ります。アプリを終了して再起動しても、注文は変更されません。私はこれを複数のNSLogで確認しました。 NSOrderedSetエントリを削除するために使用する2番目の関数tableView:commitEditingStyle:forRowAtIndexPath:は完全に機能します。

私の理論では、Core DataはNSOrderedSet関係からの注文情報をその内部表現で捨てるので、オブジェクトは同じままなので、何も保存する必要はないということです。誰もこれの前にこのような何かを経験しましたか?もしそうなら、あなたは回避策を見つけましたか?

-(void) tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath 
{ 

    NSManagedObjectContext *context= [self managedObjectContext]; 

    Playlist *playlist = (Playlist*) [context objectWithID:playlistID]; 


    [playlist willChangeValueForKey:@"tracks"]; 
    NSMutableOrderedSet *exchange = [playlist mutableOrderedSetValueForKey:@"tracks"];; 

    NSInteger fromIndex = sourceIndexPath.row; 
    NSInteger toIndex = destinationIndexPath.row; 

    NSMutableArray *arrayOfTracks = [NSMutableArray arrayWithArray:[exchange array]]; 

    [arrayOfTracks exchangeObjectAtIndex:fromIndex withObjectAtIndex:toIndex]; 
    [[playlist mutableOrderedSetValueForKey:@"tracks"] removeAllObjects]; 


    [[playlist mutableOrderedSetValueForKey:@"tracks"] addObjectsFromArray:arrayOfTracks]; 
    playlist.md5Hash = nil; 
    [playlist didChangeValueForKey:@"tracks"]; 

    NSError *savingError = nil; 
    if ([context save:&savingError]){ 
     NSLog(@"Successfully saved the context for reorder"); 
    } else { 
     NSLog(@"Failed to save the context. Error = %@", savingError); } 

} 


- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if (editingStyle == UITableViewCellEditingStyleDelete) { 
     NSManagedObjectContext *context= [self managedObjectContext]; 

     Playlist *playlist = (Playlist*) [context objectWithID:playlistID]; 

     Track *track = [self.tracksFRC objectAtIndexPath:indexPath];  


     NSMutableOrderedSet *exchange = [NSMutableOrderedSet orderedSetWithOrderedSet: playlist.tracks]; 


     [exchange removeObject:track]; 
     [track removeBelongingPlaylistObject:playlist]; 
     NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [playlist.tracks count])]; 

     [[playlist mutableOrderedSetValueForKey:@"tracks"] replaceObjectsAtIndexes:indexSet withObjects:[exchange array]]; 

     playlist.md5Hash = nil; 

     NSError *savingError = nil; 
     if ([context save:&savingError]){ 
      NSLog(@"Successfully saved the context for remove entry"); 
     } else { 
      NSLog(@"Failed to save the context. Error = %@", savingError); } 
    } 
} 

EDIT:私は一度削除レコードを持つ、二回[context save:&savingError]を呼び出すことによって、問題を解決することができた、と一度彼らとの新しい順に再挿入。しかし、この修正は本当に必要ではありません。

+0

それを必要とします木。 – sobri

+0

編集した解決済みのコードを投稿できますか?私はあなたが言ったことをやったが、二度セーブを呼び出すが、それを動作させるには十分ではなかった... –

+0

これはiOS6で修正されたか?面白いのはまだ私のために働いていない笑! : ')コアデータは、すでに経験したことがあれば、編集用の痛みです!これと同様の問題を解決しようとしている! – simonthumper

答えて

8

アレイに変換する理由は何ですか? NSMutableOrderedSetが既に法にexchangeObjectAtIndex:withObjectAtIndex:

をサポートし、私はお勧めしたい:

NSMutableOrderedSet *exchange = [playlist.tracks mutableCopy]; 

NSInteger fromIndex = sourceIndexPath.row; 
NSInteger toIndex = destinationIndexPath.row; 

[exchange exchangeObjectAtIndex:fromIndex withObjectAtIndex:toIndex]; 

playlist.tracks = exchange; 

をまた、あなたがプレイリストとトラックの間に多くの関係に多くを持っているように見えるので、あなたの削除方法は[track removeBelongingPlaylistObject:playlist];すべてのためお電話の作品それ以外の場合は、メソッドを冗長にする必要があります(コンテキストの保存を除く)。迅速にikuramediaのコード@に変換

2

ができます:ケースの誰に

var exchange: NSMutableOrderedSet = playlist.tracks.mutableCopy() as! NSMutableOrderedSet 

exchange.exchangeObjectAtIndex(fromIndexPath.row, withObjectAtIndex: toIndexPath.row) 

playlist.tracks = exchange 

はあなたが大規模なオブジェクトをシャッフルする必要がある場合は、大きなパフォーマンスの改善を意味これはありがたいのiOS 6で固定しているように見える

関連する問題