应用程序必须在后台每 10 秒循环更新来自 WebService 的数据,并在主线程中根据用户的请求向用户显示数据。我还需要根据用户请求更新和删除记录。使用 runloop 完成更新。
我已经在 AppDelegate 中注册了通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextChanged:) name:NSManagedObjectContextDidSaveNotification object:nil];
- (void)contextChanged:(NSNotification*)notification
{
if ([notification object] == [self managedObjectContext]) return;
if (![NSThread isMainThread]) {
[self performSelectorOnMainThread:@selector(contextChanged:) withObject:notification waitUntilDone:YES];
return;
}
[[self managedObjectContext] mergeChangesFromContextDidSaveNotification:notification];
[self saveContext]; //do I need this here or marge save data too?
}
我有 Storage sharedInstance 类
NSOperationQueue* operationQueue;
然后从任何线程以这种方式添加的插入、更新、选择运算符:
-(void)do_something
{
[self.operationQueue addOperationWithBlock:^{
NSManagedObjectContext*moc; //creating new NSManagedObjectContext with AppDelegate.persistentStoreCoordinator
//do my staff
[moc save:&error]
}]
}
问题是当我尝试使用 @"my_id=%@", @(my_id) 更新实体时
[moc countForFetchRequest:fetchRequest error:&error]
返回 0 并导致插入重复的存在实体问题出在同步上。请指教。我应该使用 dispatch_queue_create("com.my.", 0); 的实例吗?而不是每个 CoreData 操作?
我确实尝试过删除 operationQuiue
-(void)query:(void(^)(NSManagedObjectContext *context))queryBlock
{
NSLog(@"query CALL");
__block NSManagedObjectContext *context;
//if remove dispatch_sync and/or run in main thread result the same
dispatch_sync( dispatch_queue_create("com.myapp.db-queue", 0), ^{
AppDelegate*app = AppDelegate();
//same result if I use
//app.persistentStoreCoordinator or
//[app.managedObjectContext persistentStoreCoordinator]
NSPersistentStoreCoordinator *persistentStoreCoordinator= [app.managedObjectContext persistentStoreCoordinator];
context = [NSManagedObjectContext new];
[context setPersistentStoreCoordinator:persistentStoreCoordinator];
[context setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
queryBlock(context);
if ([context hasChanges])
{
NSError*err;
[context save:&err];
if (err) {
NSLog(@"context save: %@",[err localizedDescription]);
}
}
});
}
并将其称为:
CoreStorage* cs = [CoreStorage sharedInstance];
NSArray* list = [ws GetSections]; //array of NSDictionaries
//if add this to operationQuiue resunt the same
[cs query:^(NSManagedObjectContext *moc) {
NSLog(@"START");
for (NSDictionary *section in list) {
NSNumber* Id= @([[section objectForKey:@"section_id"] integerValue]);
NSFetchRequest * fetchRequest = [NSFetchRequest new];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Section" inManagedObjectContext: moc];
[fetchRequest setEntity:entity];
[fetchRequest setFetchLimit:1];
[fetchRequest setIncludesSubentities:NO];
[fetchRequest setPredicate: [NSPredicate predicateWithFormat:@"section_id=%@",Id]];
NSError *error =nil;
Section *entry;
if ([moc countForFetchRequest:fetchRequest error:&error] >0)
{
entry = [moc executeFetchRequest:fetchRequest error:nil][0];
NSLog(@"exist"); //this never call
}
else
{
entry = [NSEntityDescription insertNewObjectForEntityForName:@"Section" inManagedObjectContext:moc];
NSLog(@"NEW");
}
entry.section_id = Id;
entry.timeStamp = [NSDate date];
}
}];
请问有什么建议吗?