2013-01-25 1 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]; 
      }); 
     } 
    }]; 
} 
관련 문제