• 【MyBean调试笔记】关于单元的释放顺序


    【概述】

    DEMO提交人:惠商软件  2508696439

    问题描述:MDIConsole, DEMO如果Forms单元引用顺序放在mybean.console.pas文件之后如下图所示时:

    image

    创建同一EXE内的MDI子插件并显示,在不关闭MDI子窗体的情况下,关闭主EXE时,会造成关闭时产生访问违规错误。

    image

    【调试过程】

    看了问题,能重现,能重新的问题就不算什么问题了,一定可以找到原因的,开启debug dcus后,发现错误停留产生时,停留在Screen.FSaveFocusedXXX这一句。调试发现果然Screen为nil了。

    (PEV87O}1LU$O[ESGWQ_R_K

    【问题分析】

    mybean在创建插件TComponent子插件时会传入beanFactory.VclOwners, 这样在程序关闭时,清理类工厂时,会释放他,并清理他的子组件,达到自动清理的插件的目的,因为getBean的插件没有手动关闭,是等待清理beanFactory时进行清理的,清理的时候,Screen已经被清理,所以产生了该错误。

    我们看看工程文件的引用顺序

    program MDIConsole;
    
    uses
      FastMM4,
      FastMM4Messages,
    
      mybean.console,
      mybean.core.beanFactory,
    
      Forms,

    上面代码来看是会先清理Forms,然后再清理mybean.console,和mybean.core.beanFactory单元,但是因为mybean.core.beanFactory里面引用了Forms单元,所以清理顺序变成了

    1.mybean.core.beanFactory,

    2.Forms,

    3.mybean.console,

    mybean.console单元中管理了所由的类工厂插件接口,因为类工厂是通过接口来决定生命周期的,所以在清理mybean.console单元的时候,才会释放最后一个工厂接口的引用,也就是释放vclOwners和他的子插件,这个时候application和screen实例都已经被释放了。所以procedure TCustomForm.BeforeDestruction;中访问Screen才会引发异常。

    现在来优化下mybean的核心类。

    mybean.core.beanFactory和mybean.console单元中都引用Forms单元,这样不管你顺序怎么调整,都让Forms单元成为在这两个单元后面。然后在mybean.core.beanFactory被清理时,清理工厂接口资源。

    使顺序变成这样

    1.mybean.core.beanFactory,

    2.mybean.console,

    3.Forms。

  • 相关阅读:
    彭明辉教授-《研究生完全求生手册》
    使用npm创建一个命令行工具
    #!/usr/bin/python与#!/usr/bin/env python的区别
    使用node+express搭建第一个node后端项目
    使用npm创建一个程序库包
    多项式多点求值
    2. 两数相加
    CSS实现子元素自动充满父元素的剩余空间
    侧边导航栏滚动条---CSS overflow实现
    Asp.NET Core简介
  • 原文地址:https://www.cnblogs.com/DKSoft/p/4101628.html
Copyright © 2020-2023  润新知