只有在新的iPad 3上:wait_fences:未能收到回复:10004003

所以我知道有很多这方面的问题,但据我所知这是一个独特的情况,所以我想我会张贴它。 希望这会增加一些信息,最终可能会给我们一个答案,说明为什么会发生这种情况。 我收到错误:wait_fences:未能收到回复:10004003,当我的设备旋转。 我的意见animation是从以下几点开始的:

- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration

我只是在新的iPad 3上出现错误。我在原始的iPad和iPhone上使用了与3GS完全相同的程序。 他们都没有得到wait_fences错误,他们都旋转得比iPad 3更快。

我几乎只用Core Graphics来绘制视图。 我也确保他们重新resize,所以我不会得到像素化的意见。 如果我禁用resize重绘,我不会得到这个错误(但我得到延伸的意见)。 如果我完全禁用核心graphics绘制,我不会得到错误(但是,当然,我得到黑色的意见)。

我使用时间分析器,发现挂断主要是绘制渐变: 在这里输入图像说明

我已经改变了代码来填充而不是绘制渐变,这确实缓解了这个问题。 我会说梯度是问题,除了我在其他情况下做这些animation(除了回应旋转之外),它工作得很好。

我也想指出,我已经特别注意确保我只在屏幕上animation的视图。 我知道,closures屏幕animation视图有时会导致发生此错误。

我没有包含animation代码

任何想法为什么发生这种情况? 特别是因为它只发生在iPad 3上?

对于那些会问,这是执行animation的代码。 它通常会被包装在UIViewanimation块中。

 - (void) setFramesForFocusView:(CustomControl *)focusView atX:(CGFloat)x showInput:(BOOL)showInput{ CGSize bSize = self.bounds.size; CGRect fRect = focusView.frame; fRect.size.width = bSize.width; CGRect iRect; if (focusView.inputViewIsSystemKeyboard){ if (_keyboardRect.origin.y < 0 || _keyboardRect.origin.y >= CGRectGetMaxY(self.bounds) || CGRectIsEmpty(_keyboardRect) || CGRectGetMaxY(_keyboardRect) > CGRectGetMaxY(self.bounds)) return; iRect = _keyboardRect; } else { iRect = (focusView.inputUIView && showInput) ? CGRectMake(0, bSize.height / 2, bSize.width, bSize.height / 2) : CGRectZero; } CGRect iaRect = focusView.inputAccessoryUIView.frame; CGFloat availableFieldHeight = iRect.origin.y - iaRect.size.height; iRect.size.width = bSize.width; iaRect.size.width = bSize.width; if (!showInput){ iRect.origin.y = bSize.height; } iaRect.origin.y = iRect.origin.y - iaRect.size.height; iRect.origin.x = x; iaRect.origin.x = x; focusView.inputUIView.frame = iRect; focusView.inputAccessoryUIView.frame = iaRect; if (focusView.expandInput){ fRect.origin.y = 0; fRect.size.height = availableFieldHeight; } else { if (focusView.labelPlacement != LabelPlacementTop && focusView.labelPlacement != LabelPlacementBottom){ fRect.size.height = _currentView.storedFrame.size.height + [focusView.label.text sizeWithFont:focusView.label.font].height; } fRect.origin.y = availableFieldHeight - fRect.size.height; } if (fRect.size.height > availableFieldHeight){ fRect.origin.y = 0; fRect.size.height = availableFieldHeight; } fRect.origin.x = x; [focusView setLabelPlacement:LabelPlacementTop toFrame:fRect]; } 

那很快。 @RobNapier是正确的,这是一个计时问题。 我评论了我的animation,哇,还有其他许多animation背后的意见! 即使我明确地只在屏幕上的视图animation,还有另一个ViewController接收我的意见背后的旋转事件没有我…呃知识? 我的意思是,我应该知道吗? 我写了代码。 起初我并没有意识到,因为我的观点覆盖了整个屏幕。 不幸的是,这将需要大量的重写。 我使用自定义容器控制器,现在我看到我需要重新考虑我的实现。 很多东西都是不必要的旋转/animation。 但哇…回答了很多性能问题….

更新

所以我以为我面临的问题是与其他视图控制器animation的额外视图。 但是,虽然这在技术上是正确的,但是并不像我想象的那样或按照我的想法。 我绝对确定没有其他视图是通过从窗口中删除整个根视图层次结构来animation的,只用我想要旋转的视图控制器replace它。 这绝对有帮助,但不完全。 真的,它只是“降低了酒吧”,这样我就不太可能得到“等待”的错误。 我仍然发现我在某些情况下遇到了错误。

我相信我遇到的问题是我使用UIScrollView。 我的实现有它可以pipe理的可变数量的子视图。 具体的视图是我自己定制的一个UIPickerView的实现,所以你可以想象,它所pipe理的视图数量可能会变得相当大。 我发现,如果这些子视图变得太多,我开始得到'wait_fences'错误。

所以看起来: 如果UIScollView是animation的,它将animation所有的子视图,即使这些子视图不在屏幕上。 这个很重要。 我相当怀疑,很多正在为这个错误而奋斗的人可能没有意识到这一点。 这些离线子视图中的每一个都在推动你越来越接近“wait_fences”错误。 在我的情况下解决scheme是“简单”:我要将我的UIScrollView转换为UITableView。 这将意味着重写了很多代码,但至less我知道,屏幕外的子视图将从屏幕上删除,因此不animation。

我还注意到一些其他的东西:核心graphics梯度打你很难。 如果他们不使用渐变,我可以animation更多的离屏视图。 当然,我喜欢渐变,我不愿意放弃(这就是为什么我正在重写我的PickerView),但它是有趣和重要的。

更新2

完成重写我的UIScrollView作为一个tableView,似乎已经做了伎俩。 当我旋转屏幕时,我得到没有滞后和没有wait_fences错误。

更新2

所以是的,在iPad 3上遇到wait_fences错误要比任何其他iPad / iPhone更容易。 我已经通过了我所有的代码,确保我不会在屏幕上显示任何东西,这样问题就解决了。 当我使用“沉重的”绘图程序时,我仍然在iPad 3上遇到了wait_fences错误。 东西我发现,让我打它:

  1. 梯度:梯度确实使CPU在视网膜屏幕上工作。
  2. 透明度:如果你的观点不透明,CPU很难找出视图的透明区域。
  3. 透明颜色:与视图透明度不一样。 这是层叠透明的颜色/渐变在对方的顶部,以获得“效果”,如光泽,突出什么。
  4. 纹理:我发现使用纹理使它更容易碰到wait_fences错误,但没有像渐变/透明度那样接近。