Question

I have the following code:

-(void) readAllQuestions {
    NSLog(@"Reading questions from database");

    NSManagedObjectContext* moc = self.questionsDocument.managedObjectContext;
    moc.mergePolicy = NSRollbackMergePolicy;

    NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:@"QuestionEntity"];
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"modified" ascending:YES];
    request.sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

    NSError *error;
    NSArray* results = [moc executeFetchRequest:request error:&error];
    if (error) {
        NSLog(@"Error: %@", [error localizedDescription]);
    }
    NSLog(@"Read %d question entities", [results count]);
    self.questionsArray = results;
}

questionsDocument is a UIManagedDocument

My problem is, that this code doesn't always return the entities. Well in fact it actually never does it the first time I call it. When I call it the second time it works and also when I debug.

So I think there is an asyn problem going on.

Who can help me?

initializer:

-(id)init {
    if (self = [super init]) {
        [self openDocumentIfItExistsOrCreateNew];
        [self readAllQuestions];
    }
    return self;
}

code to open document:

-(void) openDocumentIfItExistsOrCreateNew {
    QuestionsDocument* document = [self createDocument];

    if (![[NSFileManager defaultManager] fileExistsAtPath:document.fileURL.path]) {
        [self addDocument:document];
    }
    [document openWithCompletionHandler:^(BOOL success) {
        if (success == NO) {
            [NSException
             raise:NSGenericException
             format:@"Could not open the file %@ at %@",
             FILE_NAME,
             document.fileURL];
        }
    }];

    self.questionsDocument = document;
}
Was it helpful?

Solution

openWithCompletionHandler works asynchronously, which means that it only initiates opening the document in the background. The completion handler block is called later, when the document actually has been opened.

So you cannot call [self readAllQuestions] directly after [self openDocumentIfItExistsOrCreateNew]. You could for example move that into the completion handler block:

[document openWithCompletionHandler:^(BOOL success) {
    if (success) {
         [self readAllQuestions];
         ... update UI (reload table view or whatever you have) ...
    } else {
          // report error
    }
}];

OTHER TIPS

That code

NSArray* results = [moc executeFetchRequest:request error:&error];
if (error) {

is not correct.

Make that

if (results == nil) {
    NSLog (@"%@", [error localizedDescription]);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top