在核心数据中改变NSOrderedSet顺序的试验和磨难

时间:2015-07-12 11:21:52

标签: ios objective-c uitableview core-data

我有一个NSOrderedSet附加到传递到UITableViewController的Core Data对象。 managedObjectContext UITableViewControllermyNSOrderedSet正好显示tableView myNSOrderedSet。当我重新排序moveRowAtIndexPath时,应用程序崩溃了。我在- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { // BREAKPOINT: "po self.routineToEdit.exercises" shows order is 0, 1, 2 NSMutableOrderedSet *orderedSet = [self.routineToEdit.exercises mutableCopy]; [orderedSet exchangeObjectAtIndex:fromIndexPath.row withObjectAtIndex:toIndexPath.row]; // BREAKPOINT: "po self.routineToEdit.exercises" shows order is 2, 1, 0 self.routineToEdit.exercises = orderedSet; [self saveContext]; } - (void)saveContext { if (self.managedObjectContext != nil) { NSError *error = nil; if ([self.managedObjectContext hasChanges] && ![self.managedObjectContext save:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } } } 中设置了一个断点,看看发生了什么,一切都很好,直到我尝试保存它。

MyUITableViewController

我不想将我的对象传递到fetchedResultsController,而是试图使用MyUITableViewController抓取我的对象并将其显示在NSOrderedSet上。在我走这条路之前,我希望看到我可以使用从AnotherUITableViewController传入的对象重新订购2015-07-12 06:39:53.176 MyApp[26505:1105589] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString appendString:]: nil argument' *** First throw call stack: ( 0 CoreFoundation 0x00000001060dec65 __exceptionPreprocess + 165 1 libobjc.A.dylib 0x0000000105663bb7 objc_exception_throw + 45 2 CoreFoundation 0x00000001060deb9d +[NSException raise:format:] + 205 3 CoreFoundation 0x00000001060afabf mutateError + 159 4 CoreData 0x000000010591ec26 -[_NSSQLGenerator prepareMasterReorderStatementPart2ForRelationship:] + 118 5 CoreData 0x000000010598cfb8 -[NSSQLAdapter newCorrelationMasterReorderStatementPart2ForRelationship:] + 72 6 CoreData 0x00000001059a5671 -[NSSQLiteConnection writeCorrelationMasterReordersFromTracker:] + 817 7 CoreData 0x00000001059a5f81 -[NSSQLiteConnection writeCorrelationChangesFromTracker:] + 65 8 CoreData 0x0000000105997627 -[NSSQLCore writeChanges] + 1351 9 CoreData 0x00000001058d32c7 -[NSSQLCore saveChanges:] + 423 10 CoreData 0x00000001058a3e74 -[NSSQLCore executeRequest:withContext:error:] + 484 11 CoreData 0x000000010597ee3f __65-[NSPersistentStoreCoordinator executeRequest:withContext:error:]_block_invoke + 4335 12 CoreData 0x0000000105987c30 gutsOfBlockToNSPersistentStoreCoordinatorPerform + 192 13 libdispatch.dylib 0x0000000108890614 _dispatch_client_callout + 8 14 libdispatch.dylib 0x0000000108876002 _dispatch_barrier_sync_f_invoke + 365 15 CoreData 0x0000000105979245 _perform + 197 16 CoreData 0x00000001058a3a58 -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 504 17 CoreData 0x00000001058cd52d -[NSManagedObjectContext save:] + 1213 18 MyApp 0x000000010511083e -[EditRoutineTableViewController saveContext] + 222 19 MyApp 0x0000000105110673 -[EditRoutineTableViewController tableView:moveRowAtIndexPath:toIndexPath:] + 371 20 UIKit 0x0000000106817822 -[UITableView _endReorderingForCell:wasCancelled:animated:] + 565 21 UIKit 0x000000010682b89d -[UIControl touchesEnded:withEvent:] + 462 22 UIKit 0x0000000106767958 -[UIWindow _sendTouchesForEvent:] + 735 23 UIKit 0x0000000106768282 -[UIWindow sendEvent:] + 682 24 UIKit 0x000000010672e541 -[UIApplication sendEvent:] + 246 25 UIKit 0x000000010673bcdc _UIApplicationHandleEventFromQueueEvent + 18265 26 UIKit 0x000000010671659c _UIApplicationHandleEventQueue + 2066 27 CoreFoundation 0x0000000106012431 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17 28 CoreFoundation 0x00000001060082fd __CFRunLoopDoSources0 + 269 29 CoreFoundation 0x0000000106007934 __CFRunLoopRun + 868 30 CoreFoundation 0x0000000106007366 CFRunLoopRunSpecific + 470 31 GraphicsServices 0x000000010a12ba3e GSEventRunModal + 161 32 UIKit 0x00000001067198c0 UIApplicationMain + 1282 33 MyApp 0x000000010510a05f main + 111 34 libdyld.dylib 0x00000001088c4145 start + 1

这是我崩溃的控制台输出:

SELECT COUNT(*) FROM taps GROUP BY(DATE(time_stamp))

感谢您的阅读。我欢迎你的意见。

我发现这个问题出现在我遇到的问题的“相同邻域”中,但是我的集合的顺序并不像示例中给出的示例那样是静态的。

Core Data ordering with a UITableView and NSOrderedSet

3 个答案:

答案 0 :(得分:1)

我认为获取结果控制器在这里没有给你任何好处(主要是由于这里没有意义的排序要求)。

我将直接使用有序集(正在编辑的对象的多对多关系)来通知您的表视图数据源。我会检查将新订购的有序集分配回对象是否按预期工作。

答案 1 :(得分:1)

StackOverflow的共识似乎是核心数据如何处理NSOrderedSet关系的错误。我能够使用Dmitry Makarenko关于Xcode生成的访问器的帖子中包含的信息来操纵NSOrderedSet的顺序:

Exception thrown in NSOrderedSet generated accessors

我还清理了(至少我认为是这样)用于在UITableView中移动行的代码:

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
    NSMutableOrderedSet *orderedSet = [self.routineToEdit mutableOrderedSetValueForKey:@"stretches"].mutableCopy;

    // This is necessary, as exchangeObjectAtIndex:withObjectAtIndex doesn't work passing in indexPath.row
    NSInteger fromIndex = fromIndexPath.row;
    NSInteger toIndex = toIndexPath.row;

    // Swap objects at indexes
    [orderedSet exchangeObjectAtIndex:fromIndex withObjectAtIndex:toIndex];
    NSLog(@"ending orderedSet = /n%@", orderedSet);

    // Assign NSMutableOrderdSet to the object's NSOrderedSet
    self.routineToEdit.stretches = orderedSet;

    // Added performBlockAndWait so the save is complete before doing anything else
    [self.persistentStoreCoordinator performBlockAndWait:^{
        [self saveContext];
    }];

}

在交换UITableView行/ NSObject之后将对象保存到managedObjectContext是至关重要的 - 当我单击完成IBAction w时,我看到并未保存所有更改时发现了这一点/在那里调用的save方法:

[self.persistentStoreCoordinator performBlockAndWait:^{
            [self saveContext];
        }];

...但应用程序仍然崩溃。

最后,我将两个BOTH实体之间的关系改为有序,这就是诀窍:

crash on coredata ios8

就我的目的而言,这已足够。我独立地尝试了这些修复中的每一个,并且它们都没有独立工作。此时,我的应用程序按照我想要的方式工作,所以我暂时不管它。

答案 2 :(得分:0)

通过致电mutableOrderedSetValueForKey:,您已经到了一半,请勿致电mutableCopy!另外,请勿将此可变有序集重新分配回exercises。只需保存您的上下文,就上下文调用refreshObject:mergeChanges:exercises应反映您的更改。