关于didEnterRegion并发问题的NSFetchRequest

时间:2015-04-07 14:37:40

标签: ios core-data nsmanagedobjectcontext

我是Core Data的新手,我查看过许多与Cored Data相关的问题,但我无法完全理解Core Data和并发的整个概念。似乎有一种方法可以做到这一点,但近年来它发生了变化,现在有点难以过滤哪些信息是最新的,哪些不是。 我正在开发一个小应用程序,它从Web服务导入商店数据,将其呈现给用户并监视用户何时进入特定商店的区域。 我正在使用两个NSManagedObjectContext,它们是CoreDataHelper类的一部分。这是init {/ 1}}实现为单身:

CoreDataHelper

我使用_ - (id)init { self = [super init]; if (!self) {return nil;} _model = [NSManagedObjectModel mergedModelFromBundles:nil]; _coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:_model]; _parentContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; [_parentContext performBlockAndWait:^{ [_parentContext setPersistentStoreCoordinator:_coordinator]; [_parentContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; }]; _context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; [_context setParentContext:_parentContext]; [_context setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; return self; } 向用户展示数据,使用context导入和同步背景数据。 我的问题是,当用户输入区域并调用_parentContext时,我使用以下方法检索此区域中商店的didEnterRegion

NSManagedObject

然而,有时候,并非总是如此,获取请求找不到具有给定ID的商店,即使它在那里是100%。出现这个问题的事实有时会让我得出结论,这与并发性有关。此外,我认为这可能与我在此处使用相同的- (Shop*)findShopWithID:(NSString*)shopID { NSArray* fetchedObjects; NSManagedObjectContext* context = [self getBackgroundManagedObectContext]; if(context==nil) [self sendRemoteLog:@"Context is nil"]; NSFetchRequest* fetch = [[NSFetchRequest alloc] init]; NSEntityDescription* entityDescription = [NSEntityDescription entityForName:@"Shop" inManagedObjectContext:context]; [fetch setEntity:entityDescription]; [fetch setPredicate:[NSPredicate predicateWithFormat:@"shopID==%@", shopID]]; NSError* error = nil; fetchedObjects = [context executeFetchRequest:fetch error:&error]; if ([fetchedObjects count] == 1) return [fetchedObjects objectAtIndex:0]; else { [self sendRemoteLog:[NSString stringWithFormat:@"No object found for ID %@",shopID]]; return nil; } } - (NSManagedObjectContext*)getBackgroundManagedObectContext { CoreDataHelper* cdh = [(AppDelegate*)[[UIApplication sharedApplication] delegate] cdh]; return [cdh backgroundSaveContext]; } 对象执行提取以及异步从Web服务导入数据这一事实有关。我应该改变它,但我认为这不是唯一的问题。

编辑:这是parentContext

中的保存机制
CoreDataHelper

2 个答案:

答案 0 :(得分:1)

您的猜测很可能是正确的。通过使用一个用于UI表示的上下文和一个用于后台提取的上下文,您不会遵循自己的模式。

因此,您的第一个行动方案是使用适当的背景上下文进行导入,并使用子上下文进行显示。

尽管如此,我认为将父上下文作为主UI上下文并使用子上下文在后台执行操作更合乎逻辑。然后,子上下文的“保存”会将更改推送到UI。

另外,请务必通过NSManagedObjectContextDidSaveNotification订阅NSNotificationCenter并正确合并更改,然后更新用户界面来处理更改。

答案 1 :(得分:0)

经过大量的调试和耐心,我设法找出问题所在。它与并发没有任何关系,在我的谓词中是一个愚蠢的错误。我使用以下代码行:
[fetch setPredicate:[NSPredicate predicateWithFormat:@"shopID==%@", shopID]];

我错误地将shopID用作NSString,而在我的核心数据模型中,NSManagedObject它是NSNumber。我重新考虑改变了商店ID,将其存储为NSString,现在它完全正常。但是,我仍然无法解释为什么它有时会工作,有时候不会......