2013-01-25 22 views
1

我試圖從包含170,000多個字典的JSON文件填充CoreData。 json的解析很快,但是當我開始嘗試添加到CoreData時,我很長一段時間阻塞了主線程,然後應用程序最終崩潰。它在調用方法時崩潰[UIDocument saveToUrl:forSaveOperation:completionHandler]這是我的代碼。如果任何人都知道是什麼導致它崩潰或加載CoreData更有效的方式,將不勝感激。從大型JSON加載核心數據導致應用程序崩潰

@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); 
} 

回答

1

我最終什麼事這樣做,停止我的應用程序崩潰被分配一個新的NSManagedObjectContext和peformed我所有負載的背景。保存後,我調用我的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]; 
      }); 
     } 
    }]; 
}