【问题标题】:UIWebView throwing exception for [WebActionDisablingCALayerDelegate setBeingRemoved:][WebActionDisablingCALayerDelegate setBeingRemoved:] 的 UIWebView 引发异常
【发布时间】:2014-11-11 16:51:30
【问题描述】:

在运行 iOS 8 时,我开始看到以下异常来自 UIWebView 的内心深处:

[WebActionDisablingCALayerDelegate setBeingRemoved:]:无法识别的选择器发送到实例 0x167ee900

* WebKit 在 webView:willRemoveScrollingLayer:withContentsLayer:forNode:delegate: -[WebActionDisablingCALayerDelegate setBeingRemoved:

中丢弃了一个未捕获的异常

当我更改 UIWebView 上的一些约束然后调用时,就会发生这种情况:

 self.webViewWidthConstraints.constant = newWidth;
 [self.webView setNeedsLayout];
 [self.webView layoutIfNeeded];

(这是为了重新渲染 webview 的内容以正确适应其宽度)。

幸运的是,异常被丢弃了,所以应用程序没有崩溃。为什么会发生这种情况,有什么办法可以防止吗?

【问题讨论】:

  • 我在带有 iframe 的 cordova 应用程序中遇到了同样的异常。
  • 是的,与科尔多瓦(((
  • 这里也一样。不使用科尔多瓦。将简单的 web 视图显示为模态视图并旋转设备会引发此异常(仅限 iOS8,适用于 iOS7)
  • 好的,所以我为我解决了问题 - 问题出在 JS 中,计算其中一个文本字段的宽度。
  • 我目前正在将此排除规则用于 objc_exception_throw 上的断点,以防止这些异常暂停调试器:!(BOOL)[[$r0 reason] hasPrefix:@"-[WebActionDisablingCALayerDelegate setBeingRemoved:] "]

标签: ios objective-c uiwebview ios8


【解决方案1】:

我发现通过添加“-webkit-transform: translateZ(0px);”到可滚动内容(我的可滚动容器中有一个 div),它为我解决了这个问题。希望这会有所帮助。

【讨论】:

  • 我把它放在我的body 标签上,它修复了一切
  • 由于您不能要求万维网添加-webkit-transform,因此解决方案在于迁移到WKWebView,因为UIWebView 本质上已被弃用。
【解决方案2】:

不确定这是否是您的情况,但我也开始在 iOS 8 上看到此问题,我们将其追踪到 iframe 上以下 CSS 属性的使用情况:

-webkit-overflow-scrolling: touch;

删除它后,我们不再有这些错误消息。

注意:在我的例子中,它不是在响应更改任何约束时发生的,而是在我们浏览 HTML 时发生的。

【讨论】:

  • 在我的例子中,当有两个或更多 <div> 元素出现在具有 -webkit-overflow-scrolling: touch; 属性的单个 web 视图中时,就会发生这种情况。
【解决方案3】:

由于给出的答案都不能帮助我,我不得不在 Objective-C 运行时的帮助下解决这个问题。

首先我提供了一个简单的函数:

id setBeingRemoved(id self, SEL selector, ...)
{
   return nil;
}

然后这两行:

    Class class = NSClassFromString(@"WebActionDisablingCALayerDelegate");
    class_addMethod(class, @selector(setBeingRemoved:), setBeingRemoved, NULL);

它有效。

【讨论】:

  • 请问,您能否提供有关此实施的更多详细信息?我试图实现它,但遇到了很多问题。谢谢
  • 嗨!您具体需要哪些详细信息?
  • 我需要覆盖更多的方法,至少在 iOS 8.4.1 中是这样。请参阅this pastebin。至少,它现在似乎没有崩溃。我几乎“禁用”了该委托中的所有方法
  • 抱歉,我没听懂。你做的一切都恰到好处。你有什么问题?
  • 有时它会调用新函数,它现在有点工作。随时用我的代码更新您的答案。谢谢安德烈:)
【解决方案4】:

使用WKWebView 代替 UIWebView。 (它首先包含在 iOS 8 中)。我试过了,好像没有这个bug。此外,与前代产品相比,它可能会提高性能。似乎苹果很可能会在不久的将来制定事实上的标准,如果不是现在的话。它的接口和委托有点类似于 UIWebView。绝对值得一试。

如果您的目标是 iOS 8 之前的版本,您可以实现后备程序来加载 UIWebView 或 WKWebView,here you are 开箱即用的实现

【讨论】:

    【解决方案5】:

    在我的情况下,问题是 iframe 内容中的

    。表格宽度大于通过 CSS 定义的 iframe 宽度。 iframe 滚动已关闭,并且表格已将 iframe 拉伸到表格的最小计算宽度。其他副作用:iframe 的内容不完全可见(在右侧被截断)。
    |--- Available viewport width -------------|
    |--- defined and estimated iframe width ---|
    |--- table width in the iframe content > than defined iframe width ---|
    |--- iframe stretched to the calculated table width ------------------|
    

    删除表格形式的 iframe 内容已解决问题。

    【讨论】:

      【解决方案6】:

      正如@André Morujão 回答的那样,从滚动元素中删除 -webkit-overflow-scrolling:touch; 会停止异常。但是我发现只有在将display:none css 添加到滚动元素时才发生异常。

      编辑:我可以继续使用display:none 来隐藏我的滚动元素,方法是将-webkit-overflow-scrolling:touch; 放在它自己的类.scroll 中,并使用jquery 在隐藏它之前和之后从我的滚动元素中添加和删除该类:

      <style>
          .scroll
          {
               -webkit-overflow-scrolling:touch;
          }
      </style>
      <script>
      function hide()
      {
          $('#scrolling_element).removeClass('scroll');
          $('#scrolling_element).css('display', 'none');
      }
      function show()
      {
          $('#scrolling_element).css('display', 'block');
          $('#scrolling_element).addClass('scroll');
      }
      </script>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-10-25
        • 2016-08-31
        • 2013-08-02
        • 2012-10-10
        • 1970-01-01
        • 2016-02-24
        • 2019-12-08
        相关资源
        最近更新 更多