iphone - 核心数据关系即使设置也不保存

标签 iphone ios core-data nsmanagedobjectcontext save

对于 PlaylistCall 实体,我有一个强制性的 genericCall 关系,该关系在保存 PlaylistCall 之前设置。日志显示 genericCall 不是 nil,但我在尝试保存托管对象上下文时收到验证错误,指出未设置关系。

什么会导致已经设置的关系在保存期间变为零?

我已验证或尝试的内容:

  • 我使用共享单例作为整个应用程序的托管对象上下文,因此我肯定在同一个托管对象上下文中工作
  • GenericCallPlaylistCall 之间存在反向关系
  • 一时兴起,我尝试删除关系然后重新创建它,但这没有任何效果所以它看起来像是我代码中的错误而不是 Xcode 中的随机错误
  • 我尝试使用 setValue:forKey 而不是动态属性访问器(点表示法),没有任何变化

这是日志:

2013-03-25 11:48:35.400 Project[30599:c07] Supposed to add <PlaylistCall: 0xa1be450> (entity: PlaylistCall; id: 0xa17dea0 <x-coredata:///PlaylistCall/tBB209BC5-EF9A-4DAE-9A55-0001B97499392> ; data: {
    delaySetting = 0;
    genericCall = "0xd4ad520 <x-coredata://7EB1AFB2-7B49-431E-9700-275307B4D1C1/GenericCall/p367>";
    orderInTable = 4;
    playlist = nil;
    repeatSetting = 0;
    repeatType = 0;
    volumeSetting = 100;
}) with generic call <GenericCall: 0xd4c3fd0> (entity: GenericCall; id: 0xd4ad520 <x-coredata://7EB1AFB2-7B49-431E-9700-275307B4D1C1/GenericCall/p367> ; data: {
    animalCategory = "0xc0aaa80 <x-coredata://7EB1AFB2-7B49-431E-9700-275307B4D1C1/AnimalCategory/p19>";
    callDescription = "Call Name";
    numberOfTimesOnPlaylist = 0;
    numberOfTimesPlayed = 0;
    playlistCall = "0xa17dea0 <x-coredata:///PlaylistCall/tBB209BC5-EF9A-4DAE-9A55-0001B97499392>";
    soundFile = "sound_file_name";
    timeLength = "0.21";
})
2013-03-25 11:48:35.402 Project[30599:c07] Error saving.  Reason(s): 
    PlaylistCall: The attribute 'genericCall' cannot be empty.

以下是我设置和保存值的方式:

GenericCall *genericCall = [self.fetchedResultsController objectAtIndexPath:indexPath];
PlaylistCall *playlistCall = (PlaylistCall *)[NSEntityDescription insertNewObjectForEntityForName:@"PlaylistCall" inManagedObjectContext:commonContext.managedObjectContext];
[self.playlist addPlaylistCall:playlistCall withGenericCall:genericCall orderInTable:[self.playlist.playlistCalls count]];
// Note: all other attributes are setup via model defaults
[commonContext save];

我在 Playlist 中设置关系的 NSManagedObject 子类:

- (void)addPlaylistCall:(PlaylistCall *)playlistCall withGenericCall:(GenericCall *)genericCall orderInTable:(int)orderInTable
{
    NSMutableOrderedSet *tempSet = [NSMutableOrderedSet orderedSetWithOrderedSet:self.playlistCalls];
    playlistCall.genericCall = genericCall;
    playlistCall.orderInTable = [NSNumber numberWithInt:orderInTable];
    NSLog(@"Supposed to add %@ with generic call %@", playlistCall, playlistCall.genericCall);
    [tempSet addObject:playlistCall];
    self.playlistCalls = tempSet;
}

我的公共(public)托管对象上下文单例 (CommonContext) 看起来像这样(是的,我已经验证了 self.managedObjectContext 不是 nil 并且没有改变):

// Saves the managed object context
- (BOOL)save
{
    NSError *anError;
    if ([self.managedObjectContext hasChanges] && ![self.managedObjectContext save:&anError]){
        [self handleSaveError:anError];
        return NO;
    } else {
        return YES;
    }
}

对于我可能做错了什么有什么想法吗?这看起来很简单,我在我的应用程序的其他任何地方都使用相同的方法来设置关系,所以一定有一些我遗漏的东西。感谢您的宝贵时间!

最佳答案

很难确定,但这里有一个符合症状的场景:

  1. 在创建新的 PlaylistCall 之前查找现有的 GenericCall 实例。但是这个 GenericCall 已经 playlistCall 的非nil 值。
  2. 您使用新的 PlaylistCall 进行分配 playlistCall.genericCall = genericCall
  3. 已存在的 PlaylistCall 实例将其 genericCall 关系设置为 nil——因为这是一对一的关系,并且这是本例中的默认行为。
  4. 保存失败——不是因为您创建了新的 PlaylistCall,这很好,而是因为之前的 PlaylistCall 留下了悬空的 genericCall 关系。

如果发生这种情况,您需要检查现有的 playlistCall 并在保存更改之前对它做一些合理的事情——很可能是重新分配它的 genericCall指向其他东西,或者可能只是删除实例。

关于iphone - 核心数据关系即使设置也不保存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15619597/

相关文章:

ios - 如何将 Swift 中的 Core Data 与 Cloudkit 以及在许多设备上同步

iphone - 使用 __weak 属性将参数传递给 block 会导致内存泄漏吗?

ios - 如何使用 Titanium 将 db 文件保存在文档目录中

iphone - 无法复制 App Sandbox 中的项目

ios - 是否可以将蓝牙低功耗 OBDII 设备连接到 iOS?

ios - iOS 8.1 中未调用 didUpdateUserLocation

iphone - 导出 CoreData 的快捷方式是什么?

swift - 将数据写入具有持久存储的文件,swift

iphone - 如何创建从屏幕顶部推送的 UINavigationController?

iphone - iphone 中的异常处理?