帆布很酷! - 页 90

 
Nikolai Semko #:

画布是一个绑定了像素数组的对象。资源负责绑定像素数组(请参阅 bool CCanvas::Create())
经常删除和重新创建画布是不好的做法。
好的做法是在需要时创建画布,在不再需要时(例如在程序结束时)删除画布。

一旦创建了画布对象,就可以对其进行清理,覆盖每帧的像素阵列,调整画布大小并将其移动到任何地方。

谢谢,我明白了一些,但不是全部。我的理解是否正确,如果在创建画布对象后,使用ObjectDelete() 从图表中删除该对象,那么绑定到该对象的像素数组将保持不变,并且...当我再次以不同的名称创建一个新的画布对象时,内存中会创建一个新的像素阵列,因此理论上有可能填满整个内存?

还是旧的像素阵列每次都会被重新绑定到上次创建的画布对象上(因为只有通过它,所使用的画布类实例的所有功能才会开始工作)?

 
leon_17 #:

谢谢,我明白了一些,但不是全部。我的理解是否正确:如果在创建一个画布对象后,使用ObjectDelete() 从图表中删除该对象,那么与该对象绑定的像素数组将保持不变,并且....当我再次创建名称不同的新画布对象时,内存中会创建一个新的像素数组,因此理论上有可能填满所有内存?

当然,无主资源会成倍增加。

leon_17#

或者还是每次都将旧的像素阵列重新绑定到上次创建的 kanvas 对象上(因为只有通过它,使用过的 kanvas 类实例的所有功能才会开始工作)

你的想象力非常丰富。我真羡慕你。我可想不到这样的事情。:))

不过,如果保存无所有者资源的名称,就可以将其重新绑定到一个新的位图对象上。但这是精神分裂症的范畴。

 
Nikolai Semko #:

不过,如果保存了无所有者资源的名称,就可以将其重新绑定到一个新的位图对象上。但这是精神分裂症的范畴。

我收回我的话。我想我找到了这样一个有用的案例。
 
Nikolai Semko #:
我收回刚才的话。我想我找到了一个可能有用的案例。

谢谢,我只是想了解如果使用ObjectDelete() 而不是Destroy(),内存中会发生什么。我意识到,在这种情况下,如果每次都为新的画布对象生成一个新名称,那么图形资源(无所有者像素数组和其他任何东西)就会成倍增加。

如果我使用 ObjectDelete(),但随后又创建了一个具有相同名称的画布对象,那么像素数组是旧的还是新的?

p.s. 这些问题可能很愚蠢,但我需要它来了解画布


机制

 
leon_17 #:

谢谢,我只是想了解如果使用ObjectDelete() 而不是Destroy(),内存中会发生什么。我还意识到,如果每次都为新的画布对象生成一个新名称,图形资源(无所有者像素数组和其他东西)会成倍增加。

编写一个简单的脚本就可以轻松检查这一点
 
Nikolai Semko #:
写一个简单的脚本就可以轻松检查。

能告诉我怎么做吗?

 
leon_17 #:

你能告诉我怎么做吗?

像这样:

#define protected public
#include <Canvas\Canvas.mqh>
#undef protected

void OnStart() {
   while(!IsStopped()) {
      int Width =(ushort)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);  // получаем Ширину окна
      int Height=(ushort)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS); // получаем Высоту окна
      CCanvas canvas;
      if(!canvas.CreateBitmapLabel("MyCanva"+string(rand()),0,0,Width,Height,COLOR_FORMAT_ARGB_NORMALIZE)) {
         Print("Error creating canvas: ",GetLastError());
      }
      canvas.FillRectangle(rand()%Width/2,rand()%Height/2,Width/2+rand()%Width/2,Height/2+rand()%Height/2,ARGB(128,rand()%255,rand()%255,rand()%255));
      canvas.Update();
      Comment("Задействовано памяти: - " + string(TerminalInfoInteger(TERMINAL_MEMORY_USED))+ " Mb");
      Sleep(500);
      ObjectDelete(canvas.m_chart_id,canvas.m_objname);
   }
}

看看注释

运行此脚本后,别忘了重新加载终端,以便为孤儿资源释放内存。


 
Nikolai Semko #:

像这样

再看看评论:

运行此脚本后,别忘了重新加载终端,以便为孤儿资源释放内存。


非常感谢你的帮助!我以前没有这样处理过内存,我会测试一下的。
谢谢你的提示,即重载终端时会删除孤儿资源!很多这样的事情我还不太清楚。

p.s. 这个示例中的一切都很完美!有东西可以看,有东西可以想,有机会可以做实验...代码很短。

 
您能告诉我更多信息吗 如果在智能交易系统中使用 kanvas,那么在从图表 删除智能交易系统 并关闭终端时,是否有必要执行Destroy()?我也不知道如何检查。我指的是带有固定对象的工作画布。如果执行或不执行 Destroy(),内存的差异就会在错误范围内。
 
leon_17 删除智能交易系统 并关闭终端时,是否有必要执行Destroy()?我也不知道如何检查。我指的是带有固定对象的工作画布。如果执行或不执行 Destroy(),内存的差异就会在错误范围内

您不需要这样做。在画布析构函数中,它会自动执行:

                    ~iCanvas() { Destroy(); ChartRedraw();};