Problema com a criação de componentes: Campo acaba nil
-
22-08-2019 - |
Pergunta
Esta é uma continuação do projeto que eu estava trabalhando aqui: com classes que utilizam um ao outro
O conselho recebeu não resolveu o problema de referência ciruclar (mais uma vez, obrigado pela ajuda). Agora eu estou lutando w / outra coisa: TcmDataPanel.FObservingDataPanels sempre acaba = nil, aparentemente porque ele nunca é criado. (Inicialmente eu estava ficando uma violação de acesso, mas mais testes descobriu-se que FObserver sempre foi nil).
Aqui está o código relevante (é uma unidade TFrame, com TcmTPDataPanel sendo o descednent TFrame):
unit cmTPDataPanelFrame;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, cmTPBasePanelFrame, cmTPPanels, nxdb, nxllComponent;
type
TcmTPDataConnector = class;
TcmTPDataPanel = class(TcmTPBasePanel)
Database: TnxDatabase;
Session: TnxSession;
private
FDataConnector: TcmTPDataConnector;
MyNxDataBase: TnxDatabase;
MyNxSession: TnxSession;
MyRefNxDataBase: TnxDatabase;
protected
procedure Disconnect; virtual; abstract;
procedure Refresh; virtual;
procedure Requery; virtual; abstract;
public
procedure Connect;
published
property DataConnector: TcmTPDataConnector read FDataConnector write
FDataConnector;
end;
TcmTPCustomDataConnector = class(TComponent)
private
FDatabase: TnxDatabase;
FObservingDataPanels: TList;
FTableForCategories: TnxTable;
FTableForItemCategoryLinks: TnxTable;
FTableForItems: TnxTable;
procedure SetTableForItemCategoryLinks(const Value: TnxTable);
protected
procedure IterateObservers;
public
constructor Create(AOwner: TComponent);
destructor Destroy; override;
procedure Register(Instance: TcmTPDataPanel);
procedure ReportObservers;
procedure Unregister(Instance: TcmTPDataPanel);
published
property Database: TnxDatabase read FDatabase write FDatabase;
property TableForCategories: TnxTable read FTableForCategories write
FTableForCategories;
property TableForItemCategoryLinks: TnxTable read
FTableForItemCategoryLinks write SetTableForItemCategoryLinks;
property TableForItems: TnxTable read FTableForItems write FTableForItems;
end;
TcmTPDataConnector = class(TcmTPCustomDataConnector)
end;
var
cmTPDataPanel: TcmTPDataPanel;
implementation
=== e ===
{
*************************** TcmTPCustomDataConnector ***************************
}
constructor TcmTPCustomDataConnector.Create(AOwner: TComponent);
begin
ShowMessage('TcmTPCustomDataConnector.Create entered.');
// inherited Create(AOwner); // TODO : check duplicate
FObservingDataPanels := TList.Create();
end;
destructor TcmTPCustomDataConnector.Destroy;
begin
FreeAndNil(FObservingDataPanels);
//inherited Destroy; // TODO : check duplicate
end;
A linha de ShowMessage que eu esperar para correr em cmTPDataConnector.Create nunca aparece, o que me faz pensar que não está herdando o método Criar do TcmTPCUstomDataConnector. Não deveria ser?
"sente" que há algo óbvio que estou perdendo, mas eu não estou vendo isso. : - \
Duas perguntas:
1) Por que é FObservingDataPanels não ser criado?
2) O "// herdado Criar (AOwner); // TODO: verificar duplicado" e "// herdada Destruir; // TODO: CONFIRA duplicadas" linhas foram postas em pelo ModelMaker em algum ponto. Devem ser descomentadas?
P.S. Obviamente, eu ainda estou aprendendo sobre a criação e herança componente. Qualquer outra entrada e conselho é bem-vindo.
P.P.S. Muitas perguntas de mim hoje. Sinta-se livre para deixar-me saber se eu preciso deixá-lo cair abaixo de um entalhe .... (apenas tendo um dia de bônus lotes-de-perguntas aqui).
Agradecemos antecipadamente para toda e qualquer ajuda! :)
Solução
Você precisa substituir seu construtor, e depois chamar herdado como o / primeira / coisa em que construtor.
public
constructor Create(AOwner: TComponent); override;
constructor TcmTPCustomDataConnector.Create(AOwner: TComponent);
begin
inherited Create(AOwner); // TODO : check duplicate
ShowMessage('TcmTPCustomDataConnector.Create entered.');
FObservingDataPanels := TList.Create();
end;
Outras dicas
Eu estou enferrujado em Delphi, mas acho que você pode precisar de uma "substituição" na sua declaração de construtor.