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)レコード後に保存することで、いくつかのレコードの後に​​保存しようとしましたが、同じ問題が発生し、moc10ループ実行ごとに1レコードが保存されます。どうすればこの問題を解決できますか?すべてのレコードを一度に、または10回のループ実行ごとmocに保存したい。

よろしくお願いします。

4

2 に答える 2

1

あなたがする必要があるのは、あなたが承認したものにコンテキストをマージすることです。最初に:を登録し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);
    }

}

これで、Appdelegateする他のスレッドからObjectContextを保存すると、objectcontextが保存されたことが通知されます。次に、それがappdelegateのコンテキストではないかどうかを確認し、メインスレッドで実行し、通知からコンテキストをマージすることを確認します。


小さな他の人はあなたのコードで奇妙だと思います:taskDB.dateTime = [[NSDate date]retain];。日付を保持する必要はありません。プロパティは日付をコピーまたは保持する必要があります。

于 2012-07-17T11:40:27.093 に答える
0

各「[NSEntityDescriptioninsertNewObjectForEntityForName」の後に、[mocinsertedObjects]のサイズが変更されているかどうかを確認してください。

そして、保存コンテキストが呼び出されるまでメモリが不足していないかどうかを確認します。

于 2012-07-17T11:26:06.493 に答える