Swift/iOS 子视图在主线程上未立即显示
Posted
技术标签:
【中文标题】Swift/iOS 子视图在主线程上未立即显示【英文标题】:Swift/iOS Subview Not Showing Immediately, on Main Thread 【发布时间】:2014-12-30 04:08:38 【问题描述】:所以我要循环添加几个子视图到我的 ViewController 的视图中;问题是从我添加子视图开始出现约 5 秒的延迟。 添加后,我确保在子视图和我的视图上都调用 setNeedsDisplay,没有骰子。我什至使用NSThread.isMainThread()
仔细检查了代码 是否在主线程 上执行,并且它按预期返回true。这是我的确切代码:
dispatch_async(dispatch_get_main_queue())
var nib = UINib(nibName: "ProfileCard", bundle: NSBundle.mainBundle())
var profiles = self.delegate.user!.profilesToShow
//loop to add ProfileCard subviews
while profiles.count > 0 && self.deck.count < self.MAX_DECK_SIZE
println("Adding Card")
//setup subview
var card = nib.instantiateWithOwner(self, options: nil).first! as ProfileCard
card.delegate = self
card.frame = CGRect(x: (self.view.bounds.width - 300)/2, y: 100, width: 300, height: 200)
card.displayProfile(profiles.first!)
//add subview
self.view.addSubview(card)
self.view.sendSubviewToBack(card)
card.setNeedsDisplay()
self.view.setNeedsDisplay()
//add card to deck, mark as shown
self.deck.append(card)
profiles.removeAtIndex(0)
此循环中的任何打印语句在子视图实际显示之前约 5 秒运行,我不确定这是由于什么原因。我什至在子视图的 init 方法中设置了打印语句,甚至是那些以预期打印的语句。
【问题讨论】:
这段代码究竟是从哪里调用的?它是什么方法的摘录? 这是网络请求后通过 NSNotification 触发的方法的摘录。发生网络请求,触发此方法,并且应该创建和添加子视图(这就是这段代码的内容)。但是这段代码会运行,然后在子视图出现在屏幕上之前会有一段延迟。 所以你有其他代码被通知在后台线程上运行? that 代码是否尝试与后台线程上的接口对话?这可能是问题的原因。 您是否急于收到所有println
s,然后是延迟,然后是所有绘图?
这是通知调用的全部代码。为了简单起见,我只是摆脱了方法签名。我相信,这段代码“与之对话”的所有内容都已加载到内存中。
【参考方案1】:
这段代码可能没有在后台线程上运行,但您必须进入主线程这一事实表明您还有其他 em> 在后台线程上运行的代码。其他代码是问题的根源。它正在尝试与后台线程上的界面对话。这反过来又会破坏整个绘图系统。
【讨论】:
我愿意,我的网络请求发生在一个单独的线程上。但据我所知,这与后台线程之间没有发生通信。唯一来自后台的是var profiles = self.delegate.user!.profilesToShow
行,其中profilesToShow
是由单独线程填充的数组。但这就是我制作临时副本的原因...嗯:/
另外,如果发生通信,会不会在 while 循环本身内有延迟?但这一切似乎都是同时发生的,而绘图是唯一延迟的事情。
绘图是一个特殊的过程。当您的代码运行时,不会发生绘图。只有在所有代码完成后(当 CATransaction 提交时),才会进行绘图。因此,可以通过尝试在后台线程上与 整个 绘图系统进行对话来搞砸它。
哦,甚至制作一个副本(如果即使 是 一个副本),您也可以在self.delegate.user!.profilesToShow
上发生线程冲突。这不是将这些数据线程安全地向下传递到主线程的方式。
好吧,你可以进入主线程做一些事情,然后再回到后台线程。只是不要从两个不同的线程处理相同的空间。永远。以上是关于Swift/iOS 子视图在主线程上未立即显示的主要内容,如果未能解决你的问题,请参考以下文章