Если вы хотите сделать серию вычислений и показать этот прогресс, вам нужно выполнить вычисления в фоновом потоке, а затем обновить пользовательский интерфейс в основном потоке. Если вы выполнили свои вычисления в основном потоке, ваш пользовательский интерфейс никогда не будет иметь возможности обновить себя.
Но, если предположить, что вы успешно инициировали много времени вычислений в фоновом потоке, можно затем использовать таймер (или ссылку дисплея), чтобы обновить свой прогресс бар, например, определить свойство таймера:
@property (nonatomic, weak) NSTimer *timer;
затем запланировать повторяющийся таймер от основной очереди и начать свой фоновый процесс:
// start the timer
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0/60.0
target:self
selector:@selector(updateProgress:)
userInfo:nil
repeats:YES];
self.timer = timer;
// use whatever mechanism you want for initiating your background process (though dispatch queues and operation queues may be easier than dealing with threads directly)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self startTimeConsumingProcess]
});
Вы бы тогда, очевидно, реализовать updateProgress:
метод, который обновляет свой пользовательский интерфейс:
- (void)updateProgress:(NSTimer *)timer
{
// update the UI progress bar here
}
И не забудьте, что invalidate
таймер, когда ваш расчет делается или когда представление отклонено, потому что если вы этого не сделаете, то таймер будет поддерживать сильную ссылку на ваш контроллер представления, и вы будете иметь сильный опорный цикл (aka keep cycle).
Кстати, другой логический подход, вместо того, чтобы использовать таймер, чтобы просто иметь обновления фона расчет отправки пользовательского интерфейса, которые обновляют индикатор обратно в основной очереди, например,
- (void) startSomeTimeConsumingProcess
{
// start time consuming process in background queue
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
BOOL finished = NO;
while (!finished)
{
// do something, updating `finished` when done
// update UI to report the progress in the main queue, though:
dispatch_async(dispatch_get_main_queue(), ^{
// update progress UI here
});
}
});
}
Единственное соображение, связанное с этим подходом, заключается в том, как быстро этот фоновый процесс отправляет основную очередь с обновлением строки выполнения. Если он обновляется слишком быстро, вы можете отставать от основной очереди с обновлением прогресса. Следовательно, вышеприведенный подход к методу таймера (или отображения ссылки). Но если вы уверены, что эти обновления будут происходить достаточно медленно, этот альтернативный подход может быть проще.
У меня такая же проблема !!!! – flashdisk
Возможно, нить не показывает ничего, пока это не будет сделано, что я сделал из своих попыток понять! – flashdisk
Почему вы не используете блок? –