2012-02-28 7 views
9

핵심 데이터의 NSOrderedSet 관계에있는 객체 순서대로 변경 사항을 저장할 수없는 이유를 아는 사람이 있습니까? NSOrderedSet 관계에 대해 생성 된 함수를 사용하는 것이 잘 작동하지 않는 버그를 이미 알고 있으므로 항상 keypath를 사용합니다. 다음은 테이블 뷰에있는 두 함수의 코드입니다.코어 데이터의 NSOrderedSet 관계를 재정렬 할 수 없습니다.

tableView:moveRowAtIndexPath:toIndexPath:은 성공적으로 저장되지만 변경 사항은 실제로 저장되지 않습니다. 즉, [tableView reloadData];을 수행하면 변경 사항이 계속 남아 있습니다. 앱을 종료하고 다시 시작하더라도 주문은 변경되지 않았습니다. 나는 여러 NSLog로 이것을 검증했다. NSOrderedSet 항목을 삭제하는 데 사용하는 두 번째 함수 인 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); } 
    } 
} 

편집

: 나는 레코드를 제거 한 번에 두 번 [context save:&savingError]를 호출하여 문제를 해결할 수 있었고, 한 번 그들과 함께 새로운 질서에 다시 삽입. 이 수정은 실제로는 필요하지 않습니다.

+0

그것을 필요 나무. – sobri

+0

수정 된 코드를 게시 할 수 있습니까? 나는 당신이 말한대로 2 번이나 전화를했지만, 제대로 작동하지 못했습니다 ... –

+0

이것은 iOS6에서 수정 되었습니까? 재미 있은 haha를 위해 아직도 일하고 ​​있지 않다! : ') 코어 데이터는 일단 경험치가 있으면 편집을위한 부랑아의 고통입니다! 이 비슷한 문제를 해결하기 위해 찾고! – 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]; 모두에 있기 때문에 전화의 작동, 재생 목록과 트랙 사이의 많은 관계로 많은 것 같다 메서드의 다른 부분은 중복되어야합니다 (컨텍스트 저장 제외). SWIFT에 ikuramedia의 코드를 @로 변환

2

가 제공합니다 경우 사람에

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

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

playlist.tracks = exchange 

당신이 대형 오브젝트 셔플해야하는 경우 큰 성능 향상을 의미한다이 고맙게도 아이폰 OS 6에서 수정 될 것으로 보인다

관련 문제