quickhybrid / quickhybrid-ios

iOS原生端的实现
BSD 3-Clause "New" or "Revised" License
18 stars 14 forks source link

内存泄露 #2

Open a714857512 opened 6 years ago

a714857512 commented 6 years ago

桥接文件以及存储交互的模块类一直没有得到释放

a714857512 commented 6 years ago

需要注销才行 self.webView?.configuration.userContentController.removeScriptMessageHandler(forName: iOS_Native_InjectJavascript) self.webView?.configuration.userContentController.removeScriptMessageHandler(forName: iOS_Native_FlushMessageQueue) self.webView?.configuration.userContentController.removeScriptMessageHandler(forName: iOS_WKWebViewJavascriptBridge) self.webView?.configuration.userContentController.removeAllUserScripts()

AnderGH commented 6 years ago

感谢大神指正,一直没注意到这里的问题

a714857512 commented 6 years ago

@AnderGH 我试验过page、ui、navigator、auth、device、runtime等类的对象都是没有释放的。 下面这种block应该是需要用weak修饰的self。要不然就会产生循环引用, [self registerHandlerName:@"config" handler:^(id data, WVJBResponseCallback responseCallback) { NSInteger configSuccess = 1; NSString msg = @""; id listArray = [data objectForKey:@"jsApiList"]; if ([listArray isKindOfClass:[NSArray class]]) { //获取配置文件 NSString plistPath = [[NSBundle mainBundle] pathForResource:@"QHJSModules" ofType:@"plist"]; NSDictionary dic = [NSDictionary dictionaryWithContentsOfFile:plistPath]; for (NSString name in listArray) { // 读取配置文件中的路径 if ([dic.allKeys containsObject:name]) { NSString *className = dic[name]; BOOL success = [self.webloader registerHandlersWithClassName:className moduleName:name]; if (success == NO) { configSuccess = 0; msg = [NSString stringWithFormat:@"%@\n %@ API注册失败", msg, name]; } } else { msg = [NSString stringWithFormat:@"%@\n %@ API类名未找到", msg, name]; } } } else { configSuccess = 0; msg = @"jsApiList 参数错误"; }

    NSDictionary *dic = [self responseDicWithCode:configSuccess Msg:msg result:nil];
    responseCallback(dic);
}];

我是用的Swift写的代码,例如我这边就需要用[weak self]修饰,要不然不会释放。 func config() { registerHandlerName(handleName: "config") {[weak self] (data, responseCallback) in var configSuccess = 1 var msg = "" if let listArray = data["jsApiList"] as? [String] { // 获取配置文件 let plistPath = Bundle.main.path(forResource: "SHJSModules", ofType: "plist")

            let dic = NSDictionary.init(contentsOfFile: plistPath ?? "")
            for name in listArray {
                // 读取配置文件的路径
                if let keys = dic?.allKeys as? [String] {
                    if keys.contains(name) {
                        let className = (dic?[name] as? String) ?? ""
                        let success = self?.webLoader?.registerHandlers(className: className, moduleName: name)
                        if success == false {
                            configSuccess = 0
                            msg = "\(msg)\n \(name) API注册失败"
                        }
                    } else {
                        msg = "\(msg)\n \(name) API类名未找到"
                    }
                } else {
                    configSuccess = 0
                    msg = "jsApiList 参数错误"
                }
            }
        } else {
            configSuccess = 0
            msg = "jsApiList 参数错误"
        }
        responseCallback?(self?.responseDic(code: configSuccess, msg: msg, result: nil))
    }
}
a714857512 commented 6 years ago

这个macdown模板贴代码有点怪怪的。