Init()和DeInit()执行顺序 - 页 23

 
fxsaber:

原则上,你可以用一条线来做。

让它成为一条线
 
Nikolai Semko:


哪里是不含糊的?

试试这个原始的例子。在切换TF时,你会明白 "独特性"。

在这个例子中,一个带有当前时间 和价格坐标的对象在OnInit中被创建。在OnCalculate中,这个对象与价格一起移动。

在OnDeinit中,它被简单地(逻辑地)删除。

当你切换TF时,结果是该物体出现后又消失了。
为什么会发生这种情况?
因为有时 旧TF的OnDeinit会删除新TF的OnInit中已经创建的内容这不是一个错误!创建这个例子的程序员应该怎么想,而没有阅读这个分支?



用一个原始的例子来说明二胎的问题有什么意义呢?

用一个非常正确的代码的例子来代替。

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2012, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_plots   0

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {

   datetime t = TimeCurrent();
   double pr  = SymbolInfoDouble(Symbol(),SYMBOL_BID);
   if(ObjectFind(0, "InitDeinit") < 0)                 // ПРОВЕРКА СУЩЕСТВОВАНИЯ ОБЪЕКТА ПЕРЕД ЕГО СОЗДАНИЕМ ОБЯЗАТЕЛЬНА!!!
    {
     ObjectCreate(0,"InitDeinit",OBJ_ARROW_THUMB_UP,0,t,pr);
     Print(__FUNCTION__, " создан InitDeinit");
    }
    
   ObjectSetInteger(0,"InitDeinit",OBJPROP_WIDTH,50); 
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   if(UninitializeReason() != REASON_CHARTCHANGE)      // ПРОВЕРКА ПРИЧИНЫ ДЕИНИЦИАЛИЗАЦИИ РЕШАЕТ ТВОЮ ПРОБЛЕМУ НА РАЗ...
    {
     ObjectDelete(0,"InitDeinit");
     ChartRedraw(0); // ЭТО НУЖНО ТОЛЬКО НА ВЫХОДНЫЕ. В РАБОЧИЕ ДНИ НЕ БУДЕТ ЛИШНИМ, НО С ПРИХОДОМ НОВОГО ТИКА ОБЪЕКТ БУДЕТ НЕДОСТУПЕН.
     Print(__FUNCTION__, "  InitDeinit удалён");
    }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnCalculate (const int rates_total,      // размер массива price[]
                 const int prev_calculated,  // обработано баров на предыдущем вызове
                 const int begin,            // откуда начинаются значимые данные
                 const double& price[])      // массив для расчета
  {

   datetime t = TimeCurrent();
   double pr  = SymbolInfoDouble(Symbol(),SYMBOL_BID);
   ObjectMove(0,"InitDeinit",0,t,pr);
   return(rates_total);
  }
//+------------------------------------------------------------------+
附加的文件:
 
Alexey Viktorov:

最好用一个几乎正确的代码的例子。

这也是一样的。该对象可以通过不相关的指标副本的Deinit来删除。而实际的OnInit是在这个事件之前执行的。

但是,显示从旧副本的OnDeinit到新副本的OnInit的任何信息的转移 要好得多。实际上,这就是问题的关键。

 
fxsaber:
这也是一样的。该对象可以通过不相关的指标副本的Deinit来删除。而实际的OnInit是在这个事件之前执行的。
if(UninitializeReason() != REASON_CHARTCHANGE)
 {
  // Если причина деинициализации смена периода графика сюда не попадаем и объекты не удаляются.
 }

在所有其他情况下,除了拔掉计算机的电源插头,该对象将被删除。

 
fxsaber:


但更好的做法是显示从旧副本的OnDeinit到新副本的OnInit传递任何信息。这其实就是问题的关键。

我很久以前就注意到,简单的解决方案不是你的强项。:-)))
 
Alexey Viktorov:

在所有其他情况下,除了拔掉计算机的电源插头,该对象将被删除。

你已经展示了一个解决私人讨论问题的方法。一般性的表述如下
fxsaber:

可靠地将任何信息从旧拷贝的OnDeinit传递到新拷贝的OnInit

因此,这需要一个明确的OnDeinit/OnInit执行序列。我从未需要这样做,但我已经实施了解决方案的想法,没有任何问题。

 
fxsaber:
你已经展示了一个私人讨论问题的解决方案。一般情况下,可以表述如下

因此,这需要一个明确的OnDeinit/OnInit执行序列。我从来不需要这个,但我实施了这个 解决方案的想法,没有任何问题。

好吧,我并不反对。但用左手的小指头抓右耳,不适合我。而不是这样一个简单的测试来写"它"...我甚至不知道该怎么称呼它。让它成为业余 爱好者,因为受虐狂有权利存在。恕我直言,你在编程方面的专业性是很强的。

 
Alexey Viktorov:

而不是这样简单的支票,写"它"...

因此,你已经错过了这个主题所讨论的问题的重点。
 
fxsaber:
所以你没有理解这个话题所讨论的问题的本质。

我理解,但你把对问题的讨论转移到了你的能力上(不小)。

毕竟我的回答是针对一个马驹代码的具体例子,而不是针对你的能力和数据传输的例子,以及对On_Init和On_Deinit执行顺序的规定。

继续对话的目的是什么?你是想让我相信用左手小指抓右耳是非常愉快的吗?还是另一个目的?

 
Alexey Viktorov:

或者是不同的目标?

你重做的那个例子与你讨论的问题并不完全吻合。你可以展示另一个例子,它不会通过UninitializeReason 来解决。