iOS - viewDidAppear: задерживается при отображении UITableView
У меня странная проблема. У меня есть приложение панели вкладок, в котором я использую контроллер навигации для каждой из разных вкладок, и у каждого контроллера навигации есть свой собственный контроллер отображения для отображения некоторого содержимого.
Когда я касаюсь вкладки, я хочу, чтобы вкладка загружалась сразу с видом и после того, как она была загружена (viewDidAppear:
) Я хочу, чтобы он загрузил некоторые данные в методе viewDidAppear:.
Чтобы проверить эту функциональность, я настроил следующий метод. Я использую NSThread
для имитации выполнения некоторой длительной операции, которая должна выполняться в фоновом режиме, пока представление загружено. Затем я назначаю NSArray *test (nonatomic, retain) с некоторыми тестовыми данными и перезагружаю таблицу.
Я перезагружаю стол, потому что в viewDidLoad
Метод Я устанавливаю таблицу, чтобы содержать только одну пустую строку (это потому, что я прочитал, что таблица настраивается до вызова viewDidAppear:.
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
DLog(@"viewDidAppear running");
[NSThread sleepForTimeInterval:10];
NSArray *array = [[NSArray alloc] initWithObjects:@"Test1", @"Test2", @"Test3", @"Test4", @"Test5", @"Test6", nil];
self.test = array;
[array release];
[table reloadData];
}
Поэтому мое ожидаемое поведение должно заключаться в том, что при прикосновении к этой конкретной вкладке она должна загружаться мгновенно, а затем через 10 секунд она должна заполняться данными таблицы из метода viewDidAppear:. Но поведение таково, что при касании этой вкладки она ждет 10 секунд, а затем отображает представление с заполненными данными таблицы.
4 ответа
Призвание [NSThread sleepForTimeInterval:10];
будет препятствовать тому, чтобы основной поток делал какие-либо обновления, поэтому вы не сможете увидеть какие-либо изменения пользовательского интерфейса. Если вы хотите отложить перезагрузку данных таблицы, как указано выше, проверьте NSObject performSelector:withObject:afterDelay:
Ссылка на класс NSObject
Поместите код для reloadData и настройки массива в метод, вызывающий его через performSelector:withObject:afterDelay:
Другие ответы объясняют, почему ваш основной поток заблокирован, когда вы используете +[NSThread sleepForTimeInterval:]
метод.
Для обработки загрузки из Интернета вы должны перенести задачу загрузки в фоновый поток, чтобы не блокировать основной поток, как вы это сделали здесь. Вы можете добиться этого, используя Grand Central Dispatch.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL), ^{
/* Download stuff */
dispatch_async(dispatch_get_main_queue(), ^{
/* Send UI updates back to the main thread. */
[self.tableView reloadData];
});
});
Вы не кладете не ту нить спать? (А именно тот, который создаст массив)
Кажется, вы ждете 10 секунд, а затем вызвать таблицу reloadData.
Почему ты все равно ждешь? Разве вы не хотите, чтобы tableView был заполнен, как только будут доступны данные?
-(void)executeMe{
NSArray *array = [[NSArray alloc] initWithObjects:@"Test1", @"Test2", @"Test3", @"Test4", @"Test5", @"Test6", nil];
self.test = array;
[array release];
[table reloadData];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
DLog(@"viewDidAppear running");
[self performSelector:@selector(executeMe) withObject:nil afterDelay:10];
}