응용 프로그램은 백그라운드에서 매 10 초마다 루프의 WebService에서 데이터를 업데이트하고 주 스레드에서 사용자의 요청으로 데이터를 사용자에게 표시해야합니다. 또한 사용자 요청에 의해 레코드를 업데이트하고 삭제해야합니다. runloop으로 업데이트가 완료되었습니다.IOS 멀티 스레딩 NSManagedObjectContext를 동기화하는 방법?
나는
NSOperationQueue* operationQueue;
다음, 업데이트, 삽입 운영자는 모든 스레드에서이 방법을 추가 선택으로 내가 저장 sharedInstance 클래스를 가지고있는 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?
}
에 알림을 등록한 :
-(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 연산마다?
내가
-(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]);
}
}
});
}
operationQuiue
을 제거 시도로 전화 않았다하시기 바랍니다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];
}
}];
모든 sugastions?
백그라운드에서 NSManagedObjectContext에 대해 NSMergeByPropertyStoreTrumpMergePolicy를 사용하고 AppDelegate의 주 스레드에 대해 NSMergeByPropertyObjectTrumpMergePolicy를 사용합니다. –