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。另外,正如其他人所建议的,您可能希望对您的后台队列使用全局并发队列这是有意的,因为我需要累积每个视图的宽度,因此无法并行执行。