21

我的应用程序在 iOS6 中运行良好,但在未指定的即将推出的 iOS 版本中,由于 NDA 原因我无法命名,所有UIViewController过渡动画都停止工作。新视图会立即出现。我不确定这个未指定的未来 iOS 版本是否是原因,因为我在 iOS6 中偶尔会看到这种情况。

有时动画开始工作一段时间然后很快停止,这让我认为这是某种内存警告问题,但我的应用程序在大多数情况下使用的 RAM 相当合理,约为 125MB。任何人都可以提供任何建议或事情来调查吗?

4

4 回答 4

40

所描述的行为一直存在:如果您确实在后台线程上工作,然后调用 UIKit 方法,那么更新通常会以一种奇怪的方式延迟。

因此,您应该始终dispatch_async进入主队列来更新 UI。

这些错误很难捕获,因为它们并不总是可以预见的发生。

为了捕捉它们,我构建了一个方法来调动一些 UIKit 方法来检查它们是否在主线程上被调用。这允许您在忘记分派回主队列时在符号断点处停止。

https://github.com/Cocoanetics/DTFoundation/blob/develop/Core/Source/iOS/Debug/UIView%2BDTDebug.m

于 2013-08-22T06:03:19.793 回答
15

Apple 开发者论坛对此问题的一个很好的解决方法:

做这个:

[UIView setAnimationsEnabled:YES] 

动画又开始工作了。我怀疑这要么是一个直接的 iOS7 错误,要么是我的代码中某处在UIViewController后台线程上发生动画或启动,导致动画停止。可能与未指定的 iOS 未来版本无关。

于 2013-08-19T19:15:11.210 回答
0

此问题似乎是由在后台线程中执行 UIKit 操作引起的。我有一个充满 NSOperations 的预渲染缓存,它将复杂的 UIViews 渲染到 UIImages 以缓存输出。这似乎在 iOS6 中运行良好,但可能确实有点越界。我需要用将图像和文本呈现到图形缓冲区而不是使用 UIViews 和 UILabels 的东西来替换这个功能。

于 2013-08-20T18:46:32.213 回答
0

您所要做的就是在接收来自 API 的响应时更新 UI 时抓住主队列。默认情况下,Ios 使用主队列来更新 UI,但它不是 100% 有效的。因此,您必须确保 UI 得到更新仅主线程,方法如下:

DispatchQueue.main.async{
  //UI related code eg: 
  self.label.text = "abc" 
  self.button.setTitle("xyz",.normal)
  self.tableView.reloadData()
}

如果你没有抓住主线程动画可能会或可能不会工作。但是如果你使用主线程动画肯定会起作用。

在 api 响应上更新 UI 时正确的代码:

Alamofire.getApiCall(paramaters: parameters, completion:{
  response in 
  // UI related code.
  DispatchQueue.main.async{
    self.label.text = "abc" 
    self.button.setTitle("xyz",.normal)
    self.tableView.reloadData()
  }
})

不正确的代码可能会导致动画停止并导致奇怪的崩溃:

  Alamofire.getApiCall(paramaters: parameters, completion:{
  response in 
  // UI related code.
    self.label.text = "abc" 
    self.button.setTitle("xyz",.normal)
    self.tableView.reloadData()
})
于 2017-09-05T09:52:05.360 回答