1

170,000以上の辞書で構成されるJSONファイルからCoreDataにデータを入力しようとしています。jsonの解析は迅速に行われますが、CoreDataに追加しようとすると、メインスレッドが長時間ブロックされ、最終的にアプリがクラッシュします。メソッド[UIDocumentsaveToUrl:forSaveOperation:completionHandler]を呼び出すとクラッシュします。これが私のコードです。クラッシュの原因やCoreDataをロードするためのより効率的な方法を誰かが知っているなら、それは大いにありがたいことです。

@property (nonatomic, strong) UIManagedDocument *wordDatabase;

- (void)viewWillAppear:(BOOL)animated
  {
    [super viewWillAppear:animated];
    if (!self.wordDatabase) {
      NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
      url = [url URLByAppendingPathComponent:@"Word Database"];
      self.wordDatabase = [[UIManagedDocument alloc] initWithFileURL:url];
    }
 }

- (void)setWordDatabase:(UIManagedDocument *)wordDatabase
  {
    if (_wordDatabase != wordDatabase) {
      _wordDatabase = wordDatabase;
      [self useDocument];
    }
  }

- (void)useDocument
  {
    if (![[NSFileManager defaultManager] fileExistsAtPath:[self.wordDatabase.fileURL path]]) {
      // does not exist on disk, so create it
      [self.wordDatabase saveToURL:self.wordDatabase.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
          [self setupFetchedResultsController];
          [self prepopulateWordDatabaseWithDocument:self.wordDatabase];
       }];
     }
  }

- (void)prepopulateWordDatabaseWithDocument:(UIManagedDocument *)document
  {
    dispatch_queue_t fetchQ = dispatch_queue_create("Word Fetcher", NULL);
    dispatch_async(fetchQ, ^{
    //Fetch the words from the json file
    NSString *fileString = [[NSBundle mainBundle] pathForResource:@"words" ofType:@"json"];
    NSString *jsonString = [[NSString alloc] initWithContentsOfFile:fileString encoding:NSUTF8StringEncoding error: NULL];
    NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error;
    NSArray *words = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
    [document.managedObjectContext performBlock:^{
        for (NSDictionary *dictionary in words)
        {
            [Word wordFromDictionary:dictionary inManagedObjectContext:document.managedObjectContext];
        }

        [document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];
      }];
    });

   dispatch_release(fetchQ);
 }
4

1 に答える 1

1

アプリがクラッシュするのを防ぐために最終的に行ったことは、新しい NSManagedObjectContext を割り当て、すべての読み込みをバックグラウンドで実行することでした。保存した後、NSFetchedResultsController を呼び出し、テーブルが再作成されました。

- (void)prepopulateWordDatabaseWithDocument:(UIManagedDocument *)document
 {
     NSManagedObjectContext *backgroundContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
     backgroundContext.undoManager = nil;
     backgroundContext.persistentStoreCoordinator = document.managedObjectContext.persistentStoreCoordinator;
     [backgroundContext performBlock:^{
         NSString *fileString = [[NSBundle mainBundle] pathForResource:@"words" ofType:@"json"];
         NSString *jsonString = [[NSString alloc] initWithContentsOfFile:fileString encoding:NSUTF8StringEncoding error: NULL];
         NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
         NSError *parseError;
         NSArray *words = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&parseError];

         for (NSDictionary *dictionary in words)
         {
             [Word wordFromDictionary:dictionary inManagedObjectContext:backgroundContext];
         }

         NSError *loadError;
         if ([backgroundContext save:&loadError]) {
             dispatch_async(dispatch_get_main_queue(), ^{
                 [self setupFetchedResultsController];
             });
         }
     }];
 }
于 2013-01-25T20:06:31.903 に答える