willSelectRowAtIndexPath / didSelectRowAtIndexPath путаница - PullRequest
2 голосов
/ 10 октября 2010

Это должно быть легко: При вызове didSelectRowAtIndexPath я запускаю сложный метод, который загружает содержимое URL, анализирует его и помещает результат в различные свойства. В симуляторе и на устройстве в ситуации WiFi все просто отлично. Однако на устройстве в более медленной сети требуется всего лишь некоторое время, чтобы обработать все это. Поэтому я хочу отобразить счетчик в ячейке выбранного ряда, чтобы успокоить пользователя в мысли, что что-то происходит.

Моя проблема в том, что вращающийся элемент появляется только во время анимированного перехода между видом, в котором была выбрана строка, и последующим видом.

Я хочу показать спиннер во время загрузки, анализа и анимации.

Я пробовал это:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
 myCustomCell = (MyCustomCell*)[tableView cellForRowAtIndexPath:indexPath];
 [myCustomCell.spinner startAnimating];
 return indexPath;
 }

и

- (NSIndexPath *)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
 myCustomCell = (EventCell*)[tableView cellForRowAtIndexPath:indexPath];
 [myCustomCell.spinner startAnimating];
 [self myVerySlowMethod];
 return indexPath;
 }

однако, кажется, что счетчик показан только между двумя видами.

Я проверил это на реальном устройстве, и мне так и не удалось показать счетчик.

Это:

а) потому что myVerySlowMethod достаточно быстрый? б) потому что didSelectRowAtIndexPath сначала обработает все, а затем выполнит часть отображения или c) Я должен изучить все хорошо написанные Руководства по программированию, прежде чем беспокоить вас?

Любой ответ приветствуется.

1 Ответ

1 голос
/ 10 октября 2010

проблема в том, что в обоих случаях ваш [self myVerySlowMethod] (или его эквивалент) блокирует основной поток, и поэтому ActivityIndicator не будет воспроизводиться.

Наилучшим подходом для этого является запуск myVerySlowMethod в фоновом потоке, а затем, когда он завершится, он может вызвать другой метод, который помещает новый контроллер представления в стек навигации.

Сначала вызовите метод для запуска в фоновом режиме:

[self performSelectorInBackground:(@selector(myVerySlowMethod)) withObject:nil];

Это автоматически создаст новый фоновый поток для запуска. Затем вы должны убедиться, что вы выполняете следующие действия в фоновом методе:

-(void) myMethod {
   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   // code you want to run in background thread;
   [pool drain];
}

Это необходимо, поскольку пул автоматического выпуска по умолчанию не настроен ни для каких потоков, кроме основного.

Наконец, вы захотите вставить новый контроллер представления в стек навигации в главном потоке. Если у вас есть другой метод для этого, вызовите его из фонового потока следующим образом:

[self performSelectorOnMainThread:(@selector(myOtherMethod)) withObject:nil
                    waitUntilDone:YES];

Необязательный третий параметр будет удерживать основной поток для вас, если вы хотите делать другие вещи после этого.

Надеюсь, это поможет!

...