Ios 使用GCD添加UIView

Ios 使用GCD添加UIView,ios,cocoa-touch,grand-central-dispatch,Ios,Cocoa Touch,Grand Central Dispatch,在我正在开发的应用程序中,我有一个水平的UIScrollView,它被用作一种表视图 向其中添加子视图会阻塞主线程,因此我决定改用GCD,并在后台线程中创建视图,然后将它们添加到主队列中的UIScrollView实例中 相关代码如下: NSUInteger numberOfItems = [_dataSource numberOfItemsInBandView:self]; CGFloat __block nextX = 0.0; dispatch_queue_t bgQueue = disp

在我正在开发的应用程序中,我有一个水平的
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);
nsuiger numberOfItems=[\u数据源numberOfItemsInBandView:self];
CGFloat uu块nextX=0.0;
调度队列bgQueue=调度队列创建(“带视图”,空);
对于(整数i=0;i
\u scrollView
是一个
UIScrollView
实例(正确初始化)

我希望看到子视图一个接一个地添加到
UIScrollView
中,但我所经历的是,一切都是异步运行的,然后滚动条刷新并同时添加所有子视图(这不是我所期望的)


有人能发现我在这里遗漏了什么吗?

UI
需要在主线程上进行更改。在后台线程(异步gcd队列)中执行
UI
更改将导致您所看到的未定义/不需要的行为。添加子视图似乎不太可能是问题的主要原因。问题可能在于为子视图检索数据的方式。解决方案是添加所有子视图,然后异步检索它们的数据,然后在操作完成时更新它们。也可以考虑不添加对用户看不到的视图,当用户滚动类似于<>代码> uITabeVIEW工作时,动态添加它们。但这也意味着每个创建请求都将以线性顺序发生,而不是以最并行的方式创建。如果不是期望的行为,您可以尝试将创建请求分派到一个全局并发队列上。

我认为
dispatch\u get\u main\u queue
在主线程中运行。不是这样吗?我添加了一个
NSAssert
来检查它,它没有失败……啊,我看到它们被添加回主线程,但有可能所有或大量视图都排队进入相同的主运行循环,这就是它们仍然同时出现的原因。如果你想要一个接一个的效果,我建议你使用动画。这也是我的想法(很多视图排队进入相同的运行循环)。使用动画将如何工作<代码>添加子视图:
不是“可设置动画的”…我能想到的选项是将所有可见子视图的alpha值设置为
0
(或隐藏),然后任何需要一段时间的操作(db或网络活动)都将在单独的线程上运行,操作完成后,使用另一个串行队列回调主线程以显示视图。您需要等待动画完成回调,在串行队列中等待动画完成。我认为您所做的一切正常,视图会很快创建并添加到滚动视图中。您可能希望尝试一个测试,在您可以指定延迟之后,使用dispatch_将调度包装到main。另外,正如其他人所建议的,您可能希望对您的后台队列使用全局并发队列这是有意的,因为我需要累积每个视图的宽度,因此无法并行执行。