美文网首页Flutter
iOS集成flutter混编内存泄漏问题

iOS集成flutter混编内存泄漏问题

作者: 毕小强 | 来源:发表于2019-08-23 11:40 被阅读0次

    如果不知道如何集成flutter可以看我的上一篇文章《iOS老项目集成flutter最新混编方案》

    集成flutter进入项目后发现每次进入flutter模块都是导致内存增加60M-80M并且退出flutter页面后,内存并不会释放,具体原因是由于每次进入Flutter页面都会创建新的的FlutterViewController,但退出的时候并没有释放。

    为什么google难以解决:

    由于整个FlutterEngine是用MRC的方式编写,所以内存管理比较困难,每个变量生成retain,都需要被release,如果一个实例retain了两次,只release一次,也会导致无法释放,如果设置了autorelease,就有可能提前释放,导致badasses,访问野指针。

    客观原因,一般的应用只会创建一个flutter应用,或者干脆就直接都是flutter应用,不释放就不释放,多点内存也无所谓,不影响崩溃,不影响使用,所以google照常发布1.0版。

    官方发布最新的解决方案,使用FlutterEngine初始化FlutterViewController

    FlutterViewController *flutterViewController = [[FlutterViewControlleralloc]initWithEngine:flutterEnginenibName:nilbundle:nil];

    通过类别发现,此方案确实使FlutterViewController释放,但拒网上查询资料得知google团队只是将内存泄漏转嫁到FlutterEngine对象上,并没有彻底解决内存问题,实践发现,每次打开Flutter页面内存会增长不到1M左右,与之前暴涨的80M内存相比,此方案还是在可接受范围。

    有大神彻底解决内存泄漏的问题,通过自己修改frameword的方式,有兴趣的可以了解下相关文章。传送门

    但是这个方案有个致命的缺陷,就是每次flutter升级都需要下载最新的frameword文件,对于没有能力自己编写frameword文件的同学,我更加倾向于官方的解决方案,不到1M的内存泄漏还是在可以接受的范围内的。

    官方方案:

    AppDelegate.h AppDelegate.m ViewController.m

    但是,使用官方解决方案发现我们想通过[flutterViewControllersetInitialRoute:@"route1"];通过不同的routename加载不同flutter页面不再生效,原因是在AppDelegate中运行[self.flutterEnginerunWithEntrypoint:nil];这行代码的时候,flutter已经初始化好了,这时在flutter中通过window.defaultRouteName获取到的route一直是默认的/,为了解决可以加载不同flutter页面的问题,我通过native向flutter发送消息,flutter接受到消息后加载不同页面的方法来解决。

    flutter代码 flutter代码 oc代码 oc代码

    这时问题又来了,flutter中调用eventChannel.receiveBroadcastStream(postArg).listen(onData ,onError: onError);时,OC代码中的FlutterEventChannel还未运行到,这就导致eventSink绑定不成功,所以[flutterEngine runWithEntrypoint:nil];与FlutterEventChannel对象必须同时生成,我是通过单例解决这一问题的:

    单例.h 单例.m

    项目启动初始化单例,如果等到点击进入flutter页面的时候再初始化单例,这时[flutterEngine runWithEntrypoint:nil];运行,flutter刚刚创建会导致跳转时页面会白2-3秒,所以在项目初始化时,将flutter也初始化。

    初始化单例

    代码Demo

    相关文章

      网友评论

        本文标题:iOS集成flutter混编内存泄漏问题

        本文链接:https://www.haomeiwen.com/subject/ojkosctx.html