Подтвердить что ты не робот

UICollectionView не обновляется сразу при вызове reloadData, но случайно после 30-60 секунд

Как следует из названия, мой UICollectionView не обновляет и не отображает ячейки сразу после вызова reloadData. Вместо этого он, похоже, в конечном итоге обновляет мой просмотр коллекции через 30-60 секунд. Моя настройка такова:

UICollectionView добавлен в контроллер просмотра в Storyboard с настройками delegate и dataSource для контроллера вида и стандартной настройки выхода numberOfSectionsInRow и cellForItemAtIndexPath оба реализованы и ссылаются на прототипированную ячейку и imageView внутри нее

Вот код, который идет в Twitter, получает временную шкалу, присваивает ее переменной, перезагружает табличное представление с помощью твитов, а затем просматривает твиты, чтобы найти фотографии и перезагружает представление коллекции этими элементами.

Даже если я прокомментирую код для отображения изображения, он все равно ничего не меняет.

SLRequest *timelineRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:timelineURL parameters:timelineParams];
[timelineRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
    if(responseData) {
        JSONDecoder *decoder = [[JSONDecoder alloc] init];

        NSArray *timeline = [decoder objectWithData:responseData];

        [self setTwitterTableData:timeline];

        for(NSDictionary *tweet in [self twitterTableData]) {
            if(![tweet valueForKeyPath:@"entities.media"]) { continue; }

            for(NSDictionary *photo in [[tweet objectForKey:@"entities"] objectForKey:@"media"]) {
                [[self photoStreamArray] addObject:[NSDictionary dictionaryWithObjectsAndKeys:
                                                    [photo objectForKey:@"media_url"], @"url",
                                                    [NSValue valueWithCGSize:CGSizeMake([[photo valueForKeyPath:@"sizes.large.w"] floatValue], [[photo valueForKeyPath:@"sizes.large.h"] floatValue])], @"size"
                                                    , nil]];
            }
        }

        [[self photoStreamCollectionView] reloadData];
    }
}];
4b9b3361

Ответ 1

Это классический симптом вызова методов UIKit из фонового потока. Если вы просмотрите документацию -[SLRequest performRequestWithHandler:], в ней говорится, что обработчик не гарантирует, какой поток будет запущен.

Настройте свой вызов на reloadData в блоке и передайте его на dispatch_async(); также передайте dispatch_get_main_queue() в качестве аргумента очереди.

Ответ 2

Вам необходимо отправить обновление в основной поток:

 dispatch_async(dispatch_get_main_queue(), ^{
    [self.photoStreamCollectionView reloadData];
  });

или в Swift:

dispatch_async(dispatch_get_main_queue(), {
    self.photoStreamCollectionView.reloadData()
})

Ответ 3

Apple говорит: вы не должны вызывать этот метод в середине блоков анимации, где элементы вставляются или удаляются. Вставки и удаления автоматически заставляют данные таблиц обновляться соответствующим образом.

В лицо: вы не должны вызывать этот метод в середине любой анимации (включая прокрутку UICollectionView).

Итак, вы можете:

[self.collectionView setContentOffset:CGPointZero animated:NO];
[self.collectionView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];

или отметьте уверенность в какой-либо анимации, а затем вызовите reloadData; или

[self.collectionView performBatchUpdates:^{
//insert, delete, reload, or move operations
} completion:nil];