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