0

我使用NSOperation子类,并将其保存这样的导入大型组数据:管理对象上下文保存管理对象的唯一的最后一个记录循环

- (void)main 
{ 

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
[[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSRunLoopCommonModes]; 
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init]; 
[moc setPersistentStoreCoordinator:[self persistentStoreCoordinator]]; 
[moc setUndoManager:nil]; //to make the import more effecient 
NSError *error; 

for (NSManagedObject *taskInfo in self.tasks) { //self.tasks are the xml returned from a web service 

Task *taskDB = [NSEntityDescription insertNewObjectForEntityForName:@"Task"inManagedObjectContext:moc]; 
     taskDB.taskID = [taskInfo valueForKey:@"TaskID"]; 
     taskDB.taskAssignedDate = [taskInfo valueForKey:@"TaskAssignDate"]; 
     taskDB.corporate = [self getCorporate:moc :[[taskInfo valueForKey:@"FacilityInfo"] valueForKey:@"ID"] ]; 
     taskDB.dateTime = [[NSDate date]retain]; 
     taskDB.requestNumber = [taskInfo valueForKey:@"RequestNumber"]; 


... //there are a lot of other properties for the task table 
} //for 
[moc save:&error]; 

[moc reset]; 
[pool drain], pool = nil; 

} 

managedObjectContext仅保存最后一个记录的循环和不会保存所有记录,但是,如果我将保存代码放入循环中,则managedObjectContext将按原样保存所有记录。我也尝试通过在循环中设置一个计数器以在(10)个记录之后进行保存来完成一些记录后的保存,但是同样的问题发生,每10次循环运行后moc保存一条记录。我怎么解决这个问题 ?我希望moc立即保存所有记录或每10个循环运行一次。

非常感谢。

+0

你为什么要在你的'NSManagedObjectContext'中调用reset?这将重置上下文到它的基本状态。 – rckoenes 2012-07-17 10:25:26

+0

,因为我在这个类的另一个地方使用它(在主要方法中) – JAHelia 2012-07-17 10:26:46

+0

你合并了两个ObjectContext吗? – rckoenes 2012-07-17 10:30:53

回答

1

你需要做的是将上下文合并到你的appdelegate中。 第一个寄存器的NSManagedObjectContextDidSaveNotification

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextChanged:) name:NSManagedObjectContextDidSaveNotification object:nil]; 

放入- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法这一些​​的位置。

并添加以下方法:

- (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];  

    //You could save here: 
    NSError *error = nil; 
    if(! [[self managedObjectContext] save:&error]) { 
     NSLog(@"Error saving context: %@", error); 
    } 

} 

现在是什么情况,wehen您从您的appdelegate将被通知的ObjectContext的已保存的其他线程保存ObjectContext的。接下来,检查它是否与appdelegate中的某个上下文不同,然后确保您在主线程中运行并合并通知中的上下文。


小其他你觉得在你的代码怪异:taskDB.dateTime = [[NSDate date]retain];。没有必要保留日期,财产应该复制或保留你的日期。

+0

我已经把这段代码放在应用程序委托,但没有区别它做什么..同样的问题仍然存在...只有最后一个记录被保存,当我完成循环后保存。 – JAHelia 2012-07-17 11:57:34

+0

您可能需要在合并代码之后添加其他保存。 – rckoenes 2012-07-17 11:59:10

+0

我在contextChanged方法中放置了一个NSLog,以确保它正常工作,并且没问题。 – JAHelia 2012-07-17 11:59:14

0

检查每个“[NSEntityDescription insertNewObjectForEntityForName”,如果[moc insertedObjects]的大小正在改变。

并检查是否在保存上下文被调用之前没有得到低内存。

+0

我有NSLog'ed插入的对象的数量,每个循环控制台显示1或2只...这很奇怪... – JAHelia 2012-07-17 11:47:05