保存导致“非法建立关系的尝试......”

Posted

技术标签:

【中文标题】保存导致“非法建立关系的尝试......”【英文标题】:Save causing 'Illegal attempt to establish a relationship...' 【发布时间】:2012-09-09 00:07:42 【问题描述】:

我正在将数据导入核心数据的后台线程上执行 NSOperation。为此,我首先创建导入记录(“导入”),然后导入与导入记录相关的对象。如果我保存托管对象上下文,下一次将导入的对象链接到导入记录的尝试将失败:

Illegal attempt to establish a relationship 'import' between objects in different contexts (source = <NSManagedObject: 0x1067bb730> (entity: Genre; id: 0x1053330c0 <x-coredata:///Genre/tC6A85CFE-3D0A-4E29-9186-4FD46104AEBC60> ; data: 
    import = nil;
    name = Polka;
) , destination = <NSManagedObject: 0x106736170> (entity: Import; id: 0x103b571e0 <x-coredata://440D80CF-7C56-4B6F-9778-990032A76B8B/Import/p1> ; data: <fault>))

这是精简的代码。我稍微修改了代码,通过添加一个多余的保存来演示效果;通常没有理由在那里有一个。

NSError *writeError = nil;

TNAppDelegate *del = (TNAppDelegate *)[[NSApplication sharedApplication] delegate];
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
[moc setPersistentStoreCoordinator:[del persistentStoreCoordinator]];
[moc setUndoManager:nil];

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self
       selector:@selector(mergeChanges:)
           name:NSManagedObjectContextDidSaveNotification
         object:moc];

// create import instance
NSManagedObject *import = [NSEntityDescription insertNewObjectForEntityForName:@"Import" inManagedObjectContext:moc];
[import setValue:[NSDate date] forKey:@"start"];

[moc save:&writeError];
[moc reset];

NSString *newGenre = [songDictItem objectForKey:@"Genre"];
NSManagedObject *newGenreObject = [NSEntityDescription insertNewObjectForEntityForName:@"Genre" inManagedObjectContext:moc];
[newGenreObject setValue:newGenre forKey:@"name"];
[newGenreObject setValue:import forKey:@"import"]; // BOOM!

更新:应要求,我提供了 mergeChanges: 的代码。它可以在 NSOperation 中找到。我尝试了 number 或 variations 来保存对主 MOC 的更改,但它们都以相同的方式结束。

- (void)mergeChanges:(NSNotification*)notification

    TNAppDelegate *del = (TNAppDelegate *)[[NSApplication sharedApplication] delegate];
    if ([notification object] == [del managedObjectContext]) return;

    if (![NSThread isMainThread]) 
        [self performSelectorOnMainThread:@selector(mergeChanges:) withObject:notification waitUntilDone:YES];
        return;
    

    [[del managedObjectContext] mergeChangesFromContextDidSaveNotification:notification];

【问题讨论】:

托管对象importnewGenreObject真的是在同一个托管对象上下文中创建的吗?因为错误消息表明它们不是。 代码应该很清楚:它们都来自moc 好的,我只是问,因为您“稍微修改了代码”,并且错误消息清楚地表明您尝试设置从一个 MOC 中的 Genre 对象到 Import 对象的关系在不同的 MOC 中。 啊,我明白了,对不起。不,唯一的修改是添加额外的保存以加速错误。 (否则每创建 50 次 newGenreObject 就会保存一次。) 你能显示你注册更改通知的mergeChanges:方法的代码吗? 【参考方案1】:

直到今天我还没有弄清楚到底发生了什么。最后,我重新启动了我的项目,并像 this tutorial 一样从头开始设计它。我过去曾将其用作参考,但不知何故,它需要完全采用他们的代码才能工作。

【讨论】:

以上是关于保存导致“非法建立关系的尝试......”的主要内容,如果未能解决你的问题,请参考以下文章

MySQL某些字符导致“非法混合排序规则”错误

python 保存文件时候, 去除名字中的非法字符

保存工作簿 Excel VBA 时删除非法字符

非法字符导致spring boot微服务构建在docker镜像创建过程中失败

如何解析会导致非法 C# 标识符的 JSON 字符串?

带有 JSP 的 JDBC 连接字符串 SQL Server 导致“非法转义字符”错误