在我正在开发的应用程序中,我有一个水平UIScrollView
,用作一种表格视图。
添加子视图会阻塞主线程,因此我决定使用GCD,并在后台线程中创建视图并将它们添加到主队列中的UIScrollView
实例。
相关代码如下:
NSUInteger numberOfItems = [_dataSource numberOfItemsInBandView:self];
CGFloat __block nextX = 0.0;
dispatch_queue_t bgQueue = dispatch_queue_create("bandview", NULL);
for (NSUInteger i = 0; i < numberOfItems; i++) {
dispatch_async(bgQueue, ^{
UIView *itemView = [_dataSource bandView:self viewForItemAtIndex:i];
itemView.frame = CGRectMake(nextX, 0, itemView.frame.size.width, itemView.frame.size.height);
dispatch_async(dispatch_get_main_queue(), ^{
[_scrollView addSubview:itemView];
_scrollView.contentSize = CGSizeMake(nextX, self.frame.size.height);
});
nextX += itemView.frame.size.width;
});
}
dispatch_release(bgQueue);
_scrollView
是UIScrollView
个实例(已正确初始化)。
我期望看到子视图逐个添加到UIScrollView
,但我所遇到的是所有内容都异步运行,然后滚动条刷新并立即添加所有子视图(这不是我的预期)。
有人能发现我在这里缺少的东西吗?
答案 0 :(得分:3)
UI
更改需要在主线程上进行。在后台线程(异步gcd队列)中执行UI
更改将导致您看到的未定义/不良行为。添加子视图似乎不太可能是问题的主要原因。问题可能在于为子视图检索数据的方式。解决方案是添加所有子视图,然后异步检索它们的数据,然后在操作完成时更新它们。另外,请考虑不添加对用户不可见的视图,并在用户滚动时动态添加它们,类似于UITableView
的工作方式。
答案 1 :(得分:0)
另一件值得指出的事情是你创建了一个串行队列(bandview)来调度UIView创建请求,但这也意味着每个创建请求将以线性顺序发生,而不是以尽可能最并发的方式创建。您可以尝试将创建请求分派到其中一个全局并发队列中,如果这不是所需的行为。