从大型 JSON 加载核心数据导致应用程序崩溃
Posted
技术标签:
【中文标题】从大型 JSON 加载核心数据导致应用程序崩溃【英文标题】:Loading Core Data From Large JSON Causing App To Crash 【发布时间】:2013-01-25 02:32:16 【问题描述】:我正在尝试从包含 170,000 多个字典的 JSON 文件填充 CoreData。 json 的解析很快,但是当我开始尝试添加到 CoreData 时,我阻塞了主线程很长时间,然后应用程序最终崩溃了。调用方法时崩溃 [UIDocument saveToUrl: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);
【问题讨论】:
【参考方案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];
);
];
【讨论】:
以上是关于从大型 JSON 加载核心数据导致应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章
当图像保存在核心数据的集合视图中时,应用程序因内存错误而崩溃