NSFetchRequest извлекает ноль совпадений сущности из базы данных, созданной с использованием UIManagedDocument
Я использую статью Джастина Дрисколла о базовых данных с UIManagedDocument в одноэлементном шаблоне, чтобы настроить его для UITabViewController. Я запускаю приложение на симуляторе. Впервые работает нормально. База данных создана успешно, и я вижу данные в контроллере таблиц для каждой вкладки. Но когда я перезапускаю свое приложение, табличные представления пусты, потому что NSFetchRequest выбирает 0 совпадений для объекта. Тот же запрос на выборку возвращает правильный результат во время первого запуска.
Я думаю, что это связано с асинхронной природой загрузки данных и данных, не сохраняющихся автоматически перед тем, как я остановлю приложение в симуляторе. Таким образом, данные не доступны во втором запуске приложения.
То, как я делаю загрузку данных, как видно из кода. Метод fetchDataIntoDocument выполняет начальную загрузку данных.
// Обработчик документов Singleton Class
-(void) performWithDocument:(OnDocumentReady)onDocumentReady {
void (^OnDocumentDidLoad)(BOOL) = ^(BOOL Success) {
onDocumentReady(self.document);
};
if (![[NSFileManager defaultManager] fileExistsAtPath:[self.document.fileURL path]]) {
**[self fetchDataIntoDocument:self.document];**
[self.document saveToURL:self.document.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:OnDocumentDidLoad];
} else if (self.document.documentState == UIDocumentStateClosed) {
[self.document openWithCompletionHandler:OnDocumentDidLoad];
} else if (self.document.documentState == UIDocumentStateNormal) {
OnDocumentDidLoad(YES);
}
}
-(void)fetchDataIntoDocument:(UIManagedDocument *)document {
MyEntityDataController *dc= [[MyEntityDataController alloc] init];
NSDictionary *entityInfo =[dc getEntityInfo];
[document.managedObjectContext performBlock:^{
[Entity createEntityWithInfo:entityInfo inManagedObjectContext:document.managedObjectContext];
}];
}
Мой класс TableViewController
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (!self.databaseDocument) {
[[LTDatabaseDocumentHandler sharedDatabaseDocumentHandler] performWithDocument:^ (UIManagedDocument *document) {
self.databaseDocument = document;
[self populateTableViewArrayFromDocument:self.databaseDocument];
}];
}
}
В populateTableViewArrayFromDocument я выполняю свой запрос на выборку
-(void)populateTableViewArrayFromDocument:(UIManagedDocument *)document
{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Entity2"];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
NSError *error = nil;
NSArray *matches = [self.databaseDocument.managedObjectContext executeFetchRequest:request error:&error];
NSLog(@" matches count for Entity2 %d", matches.count);
for (Entity2 *entity2 in matches) {
//do stuff with data and add it to tableview array
}
}
1 ответ
Я думаю, я нашел, почему у вас есть эта проблема. Я только что столкнулся с этой проблемой, и потребовалось некоторое исследование, чтобы понять это. По сути, вы правы. Проблема действительно в асинхронной природе UIManagedDocument. Вам нужно подождать, пока документ загрузится в память, а затем выполнить выборку.
Вот код, который я использую, чтобы убедиться, что документ готов:
if ([[NSFileManager defaultManager] fileExistsAtPath:[_URLDocument path]]) {
[_managedDocument openWithCompletionHandler:^(BOOL success){
[self ready]
if (!success) {
// Handle the error.
}
}];
}
Надеюсь, это поможет, ура!