NSOperationQueue избегает помещения контроллера представления в стек контроллера навигации? - PullRequest
0 голосов
/ 23 мая 2011

У меня есть контроллер представления, который является подклассом UIViewController, в котором есть табличное представление, и каждая строка в табличном представлении связана с отдельным xml-URL.Я создал класс синтаксического анализатора, который является подклассом NSOperation, и реализовал методы для синтаксического анализа XML-файла при выделении каждой строки следующим образом:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    [self performSelectorOnMainThread:@selector(pushView) withObject:nil waitUntilDone:NO];
    [self performSelectorInBackground:@selector(parseOperation:) withObject:indexPath];
}

- (void)pushView {
    detailView = [[viewDetailsController alloc] initWithNibName:@"viewDetailsController" bundle:nil];
    [self.navigationController pushViewController:detailView animated:YES]; 
}

 - (void)parseOperation:(NSIndexPath *)indexPath {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    self.queue = [[NSOperationQueue alloc] init];
    parserClass *parser = [[parserClass alloc] initWithParseUrl:[[self.arrayOfUrls objectAtIndex:indexPath.row]delegate:self];
    [queue addOperation:parser];
    [parser release];
    [pool release];
}

Parser отлично работает, но в своем пользовательском методе делегата, который я вызвал для push viewконтроллер в верхней части стека навигационных контроллеров, контроллер представления инициализируется правильно, но новый контроллер представления не помещается на экран.

Я редактировал вопрос об использовании основного потока и фонового потока, в то время как фоновый потоккорректно работает для разбора основного потока, просто инициализирует и не выдвигает представление контроллера.В чем проблема?

1 Ответ

2 голосов
/ 23 мая 2011

Вам нужно нажать на контроллер (ы) представления в главном потоке. Используйте performSelectorOnMainThread:withObject:waitUntilDone: для вызова метода в главном потоке.

Если существует вероятность, что вы будете выдвигать несколько контроллеров представления, ваше приложение будет зависать, если контроллер представления помещается в стек, когда другой анимируется. В этом случае вам следует либо указать animated:NO, либо собрать контроллеры представления в NSArray и используйте setViewControllers:animated:, чтобы добавить их в стек.

<ч />

В ответ на ваш обновленный вопрос: Вам не нужно вызывать parseOperation: через performSelectorInBackground:withObject:, поскольку NSOperationQueue выполнит созданную NSOperation в отдельном потоке в любом случае. Я предлагаю добавить свойство delegate к вашему подклассу NSOperation и следовать этому шаблону:

MyViewController.m

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyParseOperation *parseOp = ...
    parseOp.delegate = self;
    [myOperationQueue addOperation:parseOp];
}

// Called by MyParseOperation
- (void)operationCompletedWithXML:(XML *)parsedXML
{
    // Use parsedXML to create and configure a view controller
    MyCustomViewController *vc = ...

    // Animation is OK since only one view controller will be created
    [self.navigationController pushViewController:vc animated:YES];
}

MyParseOperation.m

// Call this method once the XML has been parsed
- (void)finishUp
{
    // Invoke delegate method on the main thread
    [self.delegate performSelectorOnMainThread:@selector(operationCompletedWithXML:) withObject:self.parsedXML waitUntilDone:YES];

    // Perform additional cleanup as necessary
}
...