HTML5   发布时间:2022-04-27  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了ios – 使用WKScriptMessageHandler时内存泄漏大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
不确定我是否遇到了WebKit中的错误或者我正在做一些可怕的错误,但我无法弄清楚如何使用WKScriptmessageHandler而不会导致WKScriptmessage.body中包含的任何值泄漏.

我能够组建一个最小的Mac项目来隔离问题,但无济于事.

在主视图控制器中:

class ViewController: NSViewController {
  var webView: WKWebView?

  override func viewDidLoad() {
    super.viewDidLoad()
    let userContentController = WKUserContentController()
    userContentController.addScriptmessageHandler(self,name: "handler")
    let configuration = WKWebViewConfiguration()
    configuration.userContentController = userContentController
    webView = WKWebView(frame: CGRectZero,configuration: configuration)
    view.addSubview(webView!)

    let path = NSBundle.mainBundle().pathForresource("index",ofType: "html")
    let url = NSURL(fileURLWithPath: path!)!
    webView?.loadrequest(NSURLrequest(URL: url))
  }
}

extension ViewController: WKScriptmessageHandler {
  func userContentController(userContentController: WKUserContentController,didReceiveScriptmessage message: WKScriptmessagE) {
     print(message.body)
   }
}

然后在index.html文件中:

<html>
  <head></head>
  <body>
    <script type="text/javascript">
      webkit.messageHandlers.handler.postmessage("Here's a random number for you: " + Math.random() * 10)
    </script>
  </body>
</html>

当我运行项目然后在instruments中打开内存调试器时,我看到以下泄漏:

如果我添加一个重新加载请求的按钮,并且这样做了几十次,那么应用程序的内存占用量会不断增长,并在达到某个阈值后崩溃.在这个最小的例子中崩溃可能需要一段时间,但在我的应用程序中,我每秒收到几条消息,崩溃所需的时间不到10秒.

整个项目可以是downloaded here.

知道发生了什么事吗?

解决方法

您所看到的是WebKit错误https://bugs.webkit.org/show_bug.cgi?id=136140.它是 fixed in WebKit trunk a while ago,但似乎没有合并到任何WebKit更新中.

您可以通过向WKScriptmessage添加-dealloc来解决此问题,以补偿过度保留.它可能看起来像这样

//
//  WKScriptmessage+WKScriptmessageLeakFix.m
//  TestWebkitmessages
//
//  Created by Mark Rowe on 6/27/15.
//  Copyright © Mark Rowe.
//
//  Permission is hereby granted,free of charge,to any person obtaining a copy of this software and
//  associated documentation files (the "Software"),to deal in the Software without reStriction,//  including without limitation the rights to use,copy,modify,merge,publish,diStribute,sublicense,//  and/or sell copies of the Software,and to permit persons to whom the Software is furnished to do so,//  subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in all copies or substantial
//  portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS",WITHOUT WARRANTY OF ANY KIND,EXPRESS OR IMPLIED,INCLUDING BUT NOT
//  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITnesS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
//  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER LIABILITY,//  WHETHER IN AN ACTION OF CONTRACT,TORT OR OTHERWISE,ARISING FROM,OUT OF OR IN CONNECTION WITH THE
//  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#import <mach-o/dyld.h>
#import <objc/runtime.h>
#import <WebKit/WebKit.h>

// Work around <https://webkit.org/b/136140> WKScriptmessage leaks its body

@interface WKScriptmessage (WKScriptmessageLeakFiX)
@end

@implementation WKScriptmessage (WKScriptmessageLeakFiX)

+ (void)load
{
    // <https://webkit.org/b/136140> was fixed in WebKit trunk prior to the first v601 build being released.
    // Enable the workaround in WebKit versions < 601. In the unlikely event that the fix is BACkported,this
    // version check will need to be updated.
    int32_t version = NSVersionOfRunTimeLibrary("WebKit");
    int32_t majorVersion = version >> 16;
    if (majorVersion > 600)
        return;

    // Add our -dealloc to WKScriptmessage. If -[WKScriptmessage dealloc] already existed
    // we'd need to swap implementations instead.
    Method fixedDealloc = class_geTinstanceMethod(self,@SELEctor(fixedDealloC));
    IMP fixedDeal@L_39_19@mP = method_getImplementation(fixedDealloc);
    class_addMethod(self,@SELEctor(dealloC),fixedDeal@L_39_19@mP,method_getTypeEncoding(fixedDealloC));
}

- (void)fixedDealloc
{
    // Compensate for the over-retain in -[WKScriptmessage _initWithBody:webView:frameInfo:name:].
    [self.body release];

    // Call our WKScriptmessage's superclass -dealloc implementation.
    [super dealloc];
}

@end

将它放在项目的Objective-C文件中,将此文件的编译器标志设置为包含-fno-objc-arc,它应该为您处理泄漏.

大佬总结

以上是大佬教程为你收集整理的ios – 使用WKScriptMessageHandler时内存泄漏全部内容,希望文章能够帮你解决ios – 使用WKScriptMessageHandler时内存泄漏所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。