在PerformBlock中多次保存上下文

时间:2018-10-18 12:09:24

标签: ios objective-c core-data

我在应创建对象的流程中将其保存在CoreData中。但是根据流程,我需要每X秒更新一次对象,并使用保存的上下文对其进行更新。并且因为有可能终止coredata中的应用程序,所以应该是对象的“最新更新版本”。 问题是保存上下文后,核心数据不再保存。 双重保存不起作用的示例:

dispatch_semaphore_t waitTodoA = dispatch_semaphore_create(0);
NSManagedObjectContext *contextA = [CoreDataManager backgroundObjectContext];
[contextA performBlock:^{

    PlaceObject* placeObject  = [NSEntityDescription insertNewObjectForEntityForName:@"Places" inManagedObjectContext:contextA];
    placeObject.type = @"Flat";
    placeObject.timestamp = [[NSDate date] timeIntervalSince1970];
    [CoreDataManager saveContext:contextA];

    placeObject.address = @"Sunny beach ave. 1";
    placeObject.coordinates = @"0.0,0.0";
    [CoreDataManager saveContext:contextA];

    dispatch_semaphore_signal(waitTodoA);
}];
dispatch_semaphore_wait(waitTodoA, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)));

1 个答案:

答案 0 :(得分:1)

好的,我了解您现在要测试的内容。答案是它非常适合我。我将以下代码粘贴到基于文档的Core Data应用程序的文档子类的-readFromURL:::的末尾:

[self.managedObjectContext performBlock:^{
    Stark* stark = [NSEntityDescription insertNewObjectForEntityForName:@"Stark_entity"
                                                 inManagedObjectContext:self.managedObjectContext];

    BOOL ok ;
    NSError* error = nil;
    NSLog(@"Testing two saves in %@", self);

    stark.name = @"David";
    stark.rating = @(3);
    ok = [self.managedObjectContext save:&error];
    NSLog(@"First Save ok=%hhd error = %@", ok, error);

    stark.url = @"http://example.com";
    stark.comments = @"Did it work?";
    ok = [self.managedObjectContext save:&error];
    NSLog(@"Second Save ok=%hhd error = %@", ok, error);
}];

运行此代码后,将打印NSLogs:

Testing two saves in BkmxDoc 0x100d308f0 "Test.bmco"
First Save ok=1 error = (null)
Second Save ok=1 error = (null)

然后,在检查SQLite文件时,我发现确实已经插入了新对象,并具有上述代码分配的所有四个属性值。

我同意@vadian的观点,在其中使用dispatch_semaphore很奇怪,尽管我看不出有任何原因会导致保存失败。只是为了证明这一点,在随后的测试中,我使用dispatch_semaphore添加了这三行内容,并对其进行了重新测试,然后仍然有效。

最可能的麻烦原因是您使用CoreDataManager。注意,在我的代码中,我只使用了原始的`-[NSManagedObjectContext save:]。