使用GCD添加UIViews

时间:2011-11-04 20:07:36

标签: ios cocoa-touch grand-central-dispatch

在我正在开发的应用程序中,我有一个水平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);

_scrollViewUIScrollView个实例(已正确初始化)。

我期望看到子视图逐个添加到UIScrollView,但我所遇到的是所有内容都异步运行,然后滚动条刷新并立即添加所有子视图(这不是我的预期)。

有人能发现我在这里缺少的东西吗?

2 个答案:

答案 0 :(得分:3)

UI更改需要在主线程上进行。在后台线程(异步gcd队列)中执行UI更改将导致您看到的未定义/不良行为。添加子视图似乎不太可能是问题的主要原因。问题可能在于为子视图检索数据的方式。解决方案是添加所有子视图,然后异步检索它们的数据,然后在操作完成时更新它们。另外,请考虑不添加对用户不可见的视图,并在用户滚动时动态添加它们,类似于UITableView的工作方式。

答案 1 :(得分:0)

另一件值得指出的事情是你创建了一个串行队列(bandview)来调度UIView创建请求,但这也意味着每个创建请求将以线性顺序发生,而不是以尽可能最并发的方式创建。您可以尝试将创建请求分派到其中一个全局并发队列中,如果这不是所需的行为。