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)条记录后进行保存,在一定数量的记录后进行保存,但同样的问题发生了,moc每 10 次循环运行后保存一条记录。我怎么解决这个问题 ?我希望一次或每 10 次循环运行moc保存所有记录。

非常感谢。

4

2 回答 2

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 将收到通知,告知对象上下文已保存。接下来,检查它是否不是 appdelegate 中的某个上下文,然后确保在主线程中运行并合并通知中的上下文。


其他小人认为您的代码很奇怪:taskDB.dateTime = [[NSDate date]retain];. 无需保留日期,物业应为您复制或保留日期。

于 2012-07-17T11:40:27.093 回答
0

在每个“[NSEntityDescription insertNewObjectForEntityForName”之后检查 [moc insertedObjects] 的大小是否正在变化。

并检查在调用保存上下文之前是否内存不足。

于 2012-07-17T11:26:06.493 回答