我在托管对象上下文中创建了一个对象,但我还没有保存。此外,我创建了一个子上下文,并希望在此上下文中修改此对象。为了能够修改这个对象,我必须在子上下文中检索这个临时对象。
我使用MagicalRecord的方法MR_inContext:
,它使用方法existingObjectWithID:error:
。但是这并没有返回给定临时对象ID的对象。方法objectWithID:
似乎确实有效。我不明白为什么existingObjectWithID:error:
不起作用,objectWithID:
在这种情况下不起作用。
- (void)testTemporaryObjectInChildContext {
NSURL *modelURL = [[NSBundle bundleForClass:SSDProject.class] URLForResource:@"SSDProject" withExtension:@"momd"];
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
[coordinator MR_addInMemoryStore];
NSManagedObjectContext *mainContext = [NSManagedObjectContext MR_mainQueueContext];
mainContext.persistentStoreCoordinator = coordinator;
SSDProject *project = [SSDProject MR_createInContext:mainContext];
NSManagedObjectContext *childContext = [NSManagedObjectContext MR_confinementContextWithParent:mainContext];
// Fails
NSError *error = nil;
XCTAssertNotNil([childContext existingObjectWithID:project.objectID error:&error], @"");
NSLog(@"Error: %@", error);
// Succeeds
XCTAssertNotNil([childContext objectWithID:project.objectID], @"");
}
答案 0 :(得分:2)
existingObjectWithID:error:
返回nil
的原因只是对象不存在,因为它是来自不同上下文的临时对象。
如果您在一个托管对象上下文中创建一个对象但不保存它,则它只存在于该上下文中的 。没有其他托管对象上下文有任何了解它的方法。它不在内存中,因为它不在持久存储中,所以它们无法找到它。当您调用existingObjectWithID:error:
时,上下文会检查内存中的内容,并在必要时检查持久性存储。对于来自不同上下文的未保存对象,检查都不会找到任何内容。
保存更改后,对象将写入持久性存储文件,然后其他上下文可以找到它。此时,existingObjectWithID:error:
会为ID返回非nil
。
调用objectWithID:
将返回一个对象,但不会返回一个可以使用的对象。该方法假定您提供了有效的对象ID,因此它不会检查持久性存储。如果对象存在,则其数据将正常出现故障。如果没有,你会得到一个例外。当您知道对象存在并希望更快响应时,此方法很有用。在你的情况下,对象不存在,所以调用这个方法会给你一个定时炸弹,炸毁你的应用程序。
答案 1 :(得分:0)
objectWithID:
总是返回一个对象,但它可能无效(并且当您尝试使用它时可能会抛出异常)。 existingObjectWithID:error:
在返回之前检查是否存在,如果找不到该对象则返回nil。因此,使用existingObjectWithID:error:
是安全的选择。
您应该在尝试在其他环境中访问新对象之前保存新对象,或者只是不使用其他上下文(不清楚为什么要执行您尝试执行的操作...)。