为啥我会得到:非法尝试在不同上下文中的对象之间建立关系...

Posted

技术标签:

【中文标题】为啥我会得到:非法尝试在不同上下文中的对象之间建立关系...【英文标题】:Why do I get: Illegal attempt to establish a relationship ... between objects in different contexts为什么我会得到:非法尝试在不同上下文中的对象之间建立关系... 【发布时间】:2010-08-30 19:36:32 【问题描述】:

我只有一个托管对象上下文。

我已经修改了托管对象存储。

我想将某些字段添加到每个托管对象中。将它们一一添加到我系统中的每个对象会花费太多时间,因此我决定以编程方式将它们添加到托管对象模型中。在应用程序委托中,我首先这样做:

managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];

然后我遍历模型中的所有实体并修改它们并为每个实体设置新的属性数组:

for (NSEntityDescription *entity in entities) 
    NSAttributeDescription *idAttribute = [[NSAttributeDescription alloc] init];
    [idAttribute setName:@"id"];
    [idAttribute setAttributeType:NSStringAttributeType];
    [idAttribute setOptional:NO];
    [idAttribute setIndexed:YES];

等等。

它似乎大部分工作正常。当我尝试将对象添加到我创建的新的一对一关系时遇到问题。我从同一个托管对象上下文创建对象:

 self.action = [NSEntityDescription insertNewObjectForEntityForName:@"MobileObjectAction" inManagedObjectContext:managedObjectContext];
 self.user = [NSEntityDescription insertNewObjectForEntityForName:@"MobileUser" inManagedObjectContext:managedObjectContext];

当我到达时

 [user setAction:action];

我得到: 由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'非法尝试在不同上下文中的对象之间建立关系'动作'......

我做错了什么?

【问题讨论】:

我认为我的问题可能与用于以编程方式生成的核心数据属性的访问器有关。我想我不能再使用@dynamic,因为核心数据不知道我的属性。我可以使用@synthesize,还是必须自己编写setter 和getter。如果是这样,它们需要看起来像什么? 我创建了自己的访问器:- (MobileObjectAction *)action [self willAccessValueForKey:@"action"]; id action = [self originalValueForKey:@"action"]; [self didAccessValueForKey:@"action"];返回动作; - (void)setAction:(MobileObjectAction *)action [self willChangeValueForKey:@"action"]; [self setPrimitiveValue:action forKey:@"action"]; [self didChangeValueForKey:@"action"]; 但仍然是同样的错误 【参考方案1】:

在两个实体相关之前在代码中放置一个断点。确保它们都是NSManagedObject 的实例。

如果是,请确保它们都设置了 NSManagedObjectContext 并将其设置为相同的指针。

显然,确保它们都是有效的对象。

上述测试之一很可能会被证明是错误的。

【讨论】:

你是对的,其中一个的托管对象上下文是 nil。我不知道为什么。这是我尝试过的代码: self.action = [NSEntityDescription insertNewObjectForEntityForName:@"MobileObjectAction" inManagedObjectContext:managedObjectContext]; self.user = [NSEntityDescription insertNewObjectForEntityForName:@"MobileUser" inManagedObjectContext:managedObjectContext];然后我为两者打印出 managedObjectContext 。用户对象具有有效的托管对象上下文,但操作对象仅显示 0x0。为什么会这样?? 显然在某些时候 managedObjectContext iVar 为零。我会在这两个调用之前放置一个断言,并在它为 nil 时捕获它。然后你可以回溯它以确定原因。 当我错误地指望 isDeleted 为级联删除的对象返回 YES 时,我得到了同样的异常。如这里所建议的,检查对象是否返回 nil 上下文被证明更可靠。我有点困惑为什么 isDeleted 没有完成这项工作,但很高兴有一个解决方案。感谢您的帖子和明确的答案。 @Mike,你是如何解决nil 指针在managedObjectContext 中的问题的?【参考方案2】:

我有同样的问题并解决它:

一个上下文(没有拆分/合并)。 设置属性 -> 并获得“非法尝试建立对象之间的关系...”

所以 - W ha T 错了,我发现 F 发现并正确了吗?

答案很简单: 之前

[meeting setCreator:    [self currentUser]];

之后

[meeting setCreator:    _currentUser];

供参考

*.h

@interface
 Person*     _currentUser;

@property (readonly, retain) NSManagedObjectContext *managedObjectContext;
- (Person*)currentUser;

*.m

@synthesize managedObjectContext        = _managedObjectContext;

- (Person*)currentUser
    return _currentUser;


- (NSManagedObjectContext *) managedObjectContext 

if (_managedObjectContext != nil) 
    return _managedObjectContext;


NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) 
    _managedObjectContext = [[NSManagedObjectContext alloc] init];
    [_managedObjectContext setPersistentStoreCoordinator: coordinator];

return _managedObjectContext;

【讨论】:

以上是关于为啥我会得到:非法尝试在不同上下文中的对象之间建立关系...的主要内容,如果未能解决你的问题,请参考以下文章

NSInvalidArgumentException:非法尝试在不同上下文中的对象之间建立关系

非法尝试在不同上下文中的对象之间建立关系“对象”

非法尝试在不同上下文中的对象之间建立关系“清单”

单一上下文但“非法尝试在不同上下文中的对象之间建立关系‘xyz’

核心数据:非法尝试建立关系+(空)上下文

为啥在一个视图中有不同的上下文?