2017-08-13 4 views
10

Lesen des Experten Delphi Buch Ich habe etwas gefunden, das ich nicht verstehen kann. Der Autor hat eine Einheit mit diesem Code erstellt:Delphi Schnittstelle nicht Referenz gezählt

IToDoData = interface //CRUD 
    function ToDoCreate(aValue: TToDo): integer; 
    function ToDoRead(id: integer; out aValue: TToDo): boolean; 
    function ToDoUpdate(aValue: TToDo): boolean; 
    function ToDoDelete(id: integer): boolean; 
    procedure ToDoList(aList: TToDos); 
    end; 

Dann hat er eine DataModule und implementieren die oben Schnittstelle auf diese Weise entschieden:

type 
    TDMToDo = class(TDataModule, IToDoData) 
    // ... other code ... 
    public 
    // IToDoData 
    function ToDoCreate(aValue: TToDo): integer; 
    function ToDoRead(id: integer; out aValue: TToDo): boolean; 
    function ToDoUpdate(aValue: TToDo): boolean; 
    function ToDoDelete(id: integer): boolean; 
    procedure ToDoList(aList: TToDos); 
    end; 

So weit so gut, aber beachten Sie, dass er didn 't setzen TInterfacedObject so hier haben wir keine Methoden wie AddRef und so weiter. Meine Vermutung ist, dass der obige Code in Ordnung ist, aber es muss in den try ... finally Block eingeschlossen werden.

In der Hauptform (der Datenmoduleinheit ist die Verwendungen Klauseln natürlich) gibt es eine Funktion wie folgt aus:

function TFormToDo.GetToDoData: IToDoData; 
begin 
    if DMToDo = nil then 
    DMToDo := TDMToDo.Create(Application); 
    Result := DMToDo; 
end; 

Der obige Code ermöglicht Code wie folgt zu schreiben:

begin 
    GetToDoData.ToDoList(FToDos); 

    ListView1.BeginUpdate; 
    try 
    //populate the list 
    finally 
    ListView1.EndUpdate; 
    end; 
end; 

Führt dies nicht zu einem Speicherleck? Zumindest unter Windows. Ich bin neu in Delphi, also könnte ich scheitern, aber ich habe online gelesen, dass Android und IOs ARC hat so keine Notwendigkeit, sich um den Versuch schließlich zu kümmern.

Windows hat keine ARC, also muss ich den Versuch verwenden .. schließlich, es sei denn, es gibt eine Implementierung wie TInterfacedObject (hier ist es nicht). Ist das also ein Fehler?


Die App ist über eine ToDo-App, in der Sie Ihre Notizen schreiben/lesen/speichern. Das Datenmodul verfügt über FireDAC-Zugriffskomponenten und die Schnittstellenmethoden werden für den Zugriff auf die Datenbank verwendet. Dies ist, um eine Trennung zwischen UI und db Zeug zu halten.

+0

Es wird. Was sonst noch zu sagen, es ist ein schreckliches Wetter in Madrid :) – Victoria

+0

@Victoria gleich hier leider;) –

Antwort

15

TDataModule ist TComponent Abkömmling und TComponent implementiert IInterface und verwandte Methoden Referenzzählung

TComponent = class(TPersistent, IInterface, IInterfaceComponentReference) 

jedoch TComponent hat Verweiszählung deaktiviert und Komponenten werden entweder manuell oder durch Besitzrechtsmodell auf nicht-ARC-Compiler verwaltet.

genauer zu sein, hat TComponent Referenzzählung deaktiviert, wenn es als Wrapper für Windows COM-Objekt dient. Was ist hier nicht der Fall.

Auf ARC-Compiler gibt es eine leichte Komplikation mit manueller Verwaltung - eigentlich automatische Verwaltung, denn wenn Sie nicht zulassen, TComponent Nachkommen durch Eigentum verwaltet werden, müssen sie mit DisposeOf freigegeben werden.

TComponent Verhalten ist anders als TInterfacedObject Verhalten in Bezug auf die Zählung auf klassischen Compiler.

Im obigen Fall gibt es kein Leck, da Application dieses Datenmodul besitzt und es die Lebensdauer des Datenmoduls auf allen Compilern angemessen verwaltet.


try... finally Block ist es für die Speicherverwaltung nicht, aber BeginUpdate... EndUpdate Sie schützen müssen auf allen Compilern verlassen try...finally.

+0

Also das Hinzufügen der TInterfacedObject wäre ein Fehler oder nur etwas extra? –

+0

Wo würden Sie 'TInterfacedObject' platzieren? Du kannst nur von einer Klasse erben, und das ist 'TDataModule' hier. –

+0

Ok Danke :), so dass das Datenmodul mir bereits gibt, was ich brauche, um sicher zu sein, dass es ref gezählt wird –

Verwandte Themen