我正在使用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)记录之后进行保存,但是同样的问题发生,moc
在每10次循环运行后保存一条记录。我怎么解决这个问题 ?我希望moc
一次保存所有记录或每10次循环运行。
非常感谢。
答案 0 :(得分: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);
}
}
现在发生了什么,如果您从另一个线程保存ObjectContext,您将通知appdelegate已保存了objectcontext。接下来你检查它不是你appdelegate中的某个上下文,然后确保你在主线程中运行并合并通知中的上下文。
小的其他人认为你的代码很奇怪:taskDB.dateTime = [[NSDate date]retain];
。无需保留日期,酒店应为您复制或保留日期。
答案 1 :(得分:0)
如果[moc insertedObjects]的大小正在改变,请在每个“[NSEntityDescription insertNewObjectForEntityForName”之后检查。
并检查在调用保存上下文之前是否没有低内存。