просмотр времени обновления иерархии - PullRequest
1 голос
/ 15 ноября 2009

Я пытаюсь добавить индикатор прогресса или другое уведомление "Я сейчас занят" в мою иерархию представлений перед выполнением интенсивных вычислений, которые блокируют пользовательский интерфейс. Мой код выглядит примерно так:

//create view
[currentTopView addSubView:imBusyView];

//some initialization for the intense computation
[computation startComputing];

К сожалению, мой индикатор прогресса отображается только после завершения вычислений. Похоже, что представления не перерисовываются, пока цикл выполнения не завершится. Я почти уверен, что setNeedsDisplay и setNeedsLayout также будут ждать завершения цикла выполнения.

Как мне получить отображение немедленно?

Ответы [ 2 ]

3 голосов
/ 15 ноября 2009

Перерисовка происходит только тогда, когда ваш код возвращает управление в цикл выполнения. Поэтому проще всего было бы запланировать вызов startComputing с нулевой задержкой. Таким образом, он будет выполнен во время следующей итерации цикла выполнения (сразу после перерисовки):

[computation performSelector:@selector(startComputing) withObject:nil afterDelay:0.0];

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

1 голос
/ 15 ноября 2009

Если вы делаете тяжелые вычисления, возможно, будет хорошей идеей создать новый поток.

Здесь у меня отображается ActivityIndicator и запускается большая операция XMLParse в фоновом потоке:

- (void) setSearchParser {
 activityIndicator = [[ActivityIndicatorView alloc] initWithActivity];
 [self.view addSubview:activityIndicator];
 [NSThread detachNewThreadSelector:@selector(getSearchResults:) toTarget:self withObject:[searchParser retain]];
}

затем метод getSearchResults:

- (void) getSearchResults: (SearchResultParser *) parser {
 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 [parser startParser];
 [self performSelectorOnMainThread:@selector(searchResultsReady:) withObject:[parser data] waitUntilDone:NO];
 [pool release];
}

Итак, сначала создайте новую тему:

[NSThread detachNewThreadSelector:@selector(getSearchResults:) toTarget:self withObject:[searchParser retain]];

это означает, что весь код внутри getSearchResults будет выполняться в другом потоке. getSearchResults также получает переданный параметр "searchParser", который является большим объектом, для запуска которого требуется только вызов startParse.

Это делается в getSearchResults. Когда [parser startParser] готов, результаты передаются обратно в метод основного потока с именем searchResultsReady, и пул автоматического выпуска потоков освобождается.

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

У вас может быть небольшой класс ActivityIndicator, который я написал:

-(id) initWithActivity {
 [self initWithFrame:[self bounds]];
 [self setBackgroundColor:[UIColor blackColor]];
 [self setAlpha:0.8];
 activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
 activityView.center = CGPointMake(160, 240); 
 [self addSubview:activityView ];
 [activityView startAnimating];
 return self; 
}

- (void) dealloc {
 [activityView release];
 [super dealloc];
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...