Ios UICollectionView没有';t调用reloadData时立即更新,但在30-60秒后随机更新
正如标题所示,myIos UICollectionView没有';t调用reloadData时立即更新,但在30-60秒后随机更新,ios,objective-c,uicollectionview,Ios,Objective C,Uicollectionview,正如标题所示,myUICollectionView不会在调用reloadData后立即更新和显示单元格。相反,它似乎最终会在30-60秒后更新我的收藏视图。我的设置如下: UICollectionView添加到故事板中的view controller中,包括view controller和标准outlet设置的delegate和dataSource设置 numberOfSectionsInRow和cellForItemAtIndexPath都是实现的,并且引用了原型单元格和其中的imageVie
UICollectionView
不会在调用reloadData
后立即更新和显示单元格。相反,它似乎最终会在30-60秒后更新我的收藏视图。我的设置如下:
UICollectionView
添加到故事板中的view controller中,包括view controller和标准outlet设置的delegate
和dataSource
设置
numberOfSectionsInRow
和cellForItemAtIndexPath
都是实现的,并且引用了原型单元格和其中的imageView
下面是转到Twitter的代码,获取一个时间线,将其分配给一个变量,用tweets重新加载一个表视图,然后通过tweets查找照片,并用这些项目重新加载集合视图
即使我注释掉代码以显示图像,它仍然不会改变任何东西
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];
}
}];
这是从后台线程调用UIKit方法的典型症状。如果查看,它会说处理程序不保证它将在哪个线程上运行
将对
reloadData
的调用包装在一个块中,并将其传递给dispatch_async()
;另外,通过<代码> DeXCHOGGETMIGNEQUEQUEL()>代码>作为队列参数。 < P>苹果说:你不应该在插入或删除项目的动画块中间调用这个方法。插入和删除会自动导致表的数据得到适当更新
脸部:你不应该在任何动画中间调用这个方法(包括滚动中的UICLoopDeVIEW)。 因此,您可以:
[self.collectionView setContentOffset:CGPointZero animated:NO];
[self.collectionView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
或者标记确定没有任何动画,然后调用重载数据;
或
您需要将更新分派到主线程:
dispatch_async(dispatch_get_main_queue(), ^{
[self.photoStreamCollectionView reloadData];
});
或使用Swift:
dispatch_async(dispatch_get_main_queue(), {
self.photoStreamCollectionView.reloadData()
})
您确定这不仅仅是因为在请求完成之前不调用-reloadData吗?(这需要时间)。你赢了!完全按照您所说的方式包装代码解决了问题。UITableView和UICollectionView之间是否存在根本性的区别,即允许在UITableView上重新加载数据,但不允许在UICollectionView上重新加载数据?@nullfox很高兴它成功了!我不知道有什么区别,但如果有区别的话,很可能是不应该依赖的实施细节。唯一的做法是确保发送到任何UIKit对象的消息都在主线程上发送。几个小时的调试通过简单的修复解决了!顺便说一句,UITableView也存在同样的问题。谢谢大家!@RyJ很高兴能帮忙@Carlvaezey感谢提示“这是从后台线程调用UIKit方法的典型症状。”我从NSNotificationCenter重新加载UICollectionView时,它表现得很愚蠢。在dispatch\u async中包装重载解决了这个问题。
dispatch_async(dispatch_get_main_queue(), {
self.photoStreamCollectionView.reloadData()
})