Как изменить этот код для правильной работы? - PullRequest
2 голосов
/ 07 октября 2010

Я скачал некоторый код из http://github.com/matej/MBProgressHUD, чтобы показать индикатор выполнения при выполнении чего-либо.

Это код, который заставляет индикатор прогресса всплыть.

[HUD showWhileExecuting:@selector(myTask) onTarget:self withObject:nil animated:YES];

Это покажет индикатор прогресса во время работы метода myTask.

Странно то, что это также позволит продолжить выполнение программы ниже этой строки во время работы myTask. Это не то поведение, которое я хочу. Я хочу, чтобы индикатор выполнения отображался во время работы myTask, и только после того, как myTask завершит работу, я хочу, чтобы выполнение программы продолжалось ниже этой строки.

Это код для метода showWhileExecuting.

- (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated {

    methodForExecution = method;
    targetForExecution = [target retain];
    objectForExecution = [object retain];

    // Launch execution in new thread
 taskInProgress = YES;
    [NSThread detachNewThreadSelector:@selector(launchExecution) toTarget:self withObject:nil];

 // Show HUD view
 [self show:animated];
}

Чтобы получить желаемое поведение, я должен отредактировать этот код или сделать что-то еще?

Я попытался обойти эту проблему, установив значение bool перед вызовом этого метода, что приводит к зависанию выполнения программы в цикле while сразу после того, как значение bool изменяется в конце myTask. Это работает, но по какой-то причине это приводит к тому, что счетчик появляется только на мгновение в конце, а не повсюду, как предполагалось. Почему это так?

Ответы [ 2 ]

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

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

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

Так что с вашим циклом while на месте, представление HUD будет отображаться только после того, как завершится ваша задача. Конечно, на этом этапе пора перестать показывать вид.

Вам нужно будет переместить обработку, которую вы хотите отложить, до тех пор, пока поток не завершит свой собственный метод. Затем в конце потока вы можете использовать -performSelectorOnMainThread: ..., чтобы запустить оставшуюся обработку.

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

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

Метод, который вы вызываете, выполняет вашу задачу в новом потоке.

Ваш метод while не работает, поскольку обновление отображения пользовательского интерфейса выполняется в основном потоке. Пока вы находитесь в цикле while, вы блокируете основной поток.

Я предлагаю вам переместить код, который вы хотите запустить после завершения задачи, в новый метод. Затем, в конце вашей задачи, вызовите этот метод. (Или, наоборот, отправьте уведомление или другой сигнал.)

Кроме того, посмотрите документацию о потоках и циклах выполнения, важно понять эту тему.

...