Delphi-PRAXiS
Seite 4 von 5   « Erste     234 5      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Objekte / Freigaben / Free / Nil (https://www.delphipraxis.net/176997-objekte-freigaben-free-nil.html)

Thom 10. Okt 2013 01:45

AW: Objekte / Freigaben / Free / Nil
 
Zitat:

Zitat von stahli (Beitrag 1231491)
Das Problem ist nicht so einfach zu lösen.

Hier mal ein paar ältere Diskussionen dazu:
http://www.delphipraxis.net/166899-i...eferenzen.html

Wie die Zeit vergeht... :roll:
Auf den diesjährigen Delphi-Tagen hatte ich dazu übrigens die Funktionsweise live im Debugger demonstriert. :-D
Es funktioniert also - wenn auch (momentan) nur unter Windows, da dazu intern Assemblerfunktionen verwendet werden.

jaenicke 10. Okt 2013 06:35

AW: Objekte / Freigaben / Free / Nil
 
In den meisten Anwendungsfällen sind in so einem Fall aber eher Interfaces passend. Dann braucht man sich nicht darum zu kümmern und das Objekt wird freigegeben, wenn es von keiner Seite mehr benutzt wird. Umgekehrt hat man es aber auch überall noch, auch wenn es in der ursprünglichen Liste schon weg ist.

Alex_ITA01 10. Okt 2013 07:32

AW: Objekte / Freigaben / Free / Nil
 
Danke für die zahlreichen Hinweise.
Ich habe nur noch zwei letzte Fragen ;-)

Aktuell habe ich die Variante mit den OwnsObjects aktiv und im FormDestroy rufe ich zur Zeit nur "FreeAndNil(MyObjList);" auf. Ich habe jetzt ja gelernt, dass dann das globale Objekt "tmpObject" noch vorhanden ist aber auf ein ungültigen Speicherbereich zeigt.

1) Woher weiß der Speichermanager eigentlich, dass diese Speicheradresse "ungültig" ist? Gibt es da irgendein Flag dafür?
2) Das das "if Assigned(tmpObject) then" weiterhin nach "FreeAndNil(MyObjList);" im FormDestroy funktioniert, habe ich verstanden aber warum crasht das Programm nicht, wenn ich dann auch auf die Inhalte und Funktionen von "tmpObject" zugreife nach der "if Assigned(tmpObject) then"-Abfrage?

Gruß

stahli 10. Okt 2013 08:26

AW: Objekte / Freigaben / Free / Nil
 
Wenn Du ein Objekt freigibst wird nur der Speicherbereich als verfügbar definiert.

Wenn Du jetzt noch darauf zugreifst und der Speicher noch nicht überschreiben wurde, dann kann das noch gut gehen.
Es kann aber auch sein, dass es in unvorhergesehener Form knallt, wenn die dort stehenden Binärdaten schon (teilweise) überschreiben wurde.


In meinem aktuellen Framework habe ich übrigens folgende Lösung:

In der Datanschicht sammle ich alle erzeugten Objekte in einer sortiereten Liste.
Diese fordere ich dann zur Laufzeit anhand einer Id an. Durch Binary Search geht das wirklich schnell.
Wurde ein Objekt bereits aufgelöst, gibt die Anfrage nil zurück.
Man muss dann halt immer wieder die Objekte "abfordern".

Die Objekte müssen dafür dann auch speziell angepasst sein.
So funktioniert das gut, aber halt nur in einem festgelegten Rahmen.

Delphi-Quellcode:
function TssIO_Custom.GetObject(Id: TssId): TssObject;
var
  Index: Integer;
  ssObj: TssObject;
begin
  Result := nil;
  ssObj := TssObject.Create(nil, Id, True);
  if ssObjectList.BinarySearch(ssObj, Index) then
    Result := ssObjectList[Index];
  FreeAndNil(ssObj);
end;

procedure TssIO_Custom.RegisterObject(ssObj: TssObject);
var
  Index: Integer;
begin
  if not Assigned(ssObj) then
    Exit;
  if ssObj.HideMode then
    Exit;
  if not ssObjectList.BinarySearch(ssObj, Index) then
    ssObjectList.Insert(Index, ssObj);
end;

procedure TssIO_Custom.UnregisterObject(ssObj: TssObject);
begin
  if not Assigned(ssObj) then
    Exit;
  if ssObj.HideMode then
    Exit;
  ssObjectList.Extract(ssObj);
end;

Eine Compilerlösung, Referenzen auf aufgelöste Objekte automatisch zu nilen ist wohl nicht in Aussicht.

jaenicke 10. Okt 2013 12:05

AW: Objekte / Freigaben / Free / Nil
 
Zitat:

Zitat von stahli (Beitrag 1231518)
Eine Compilerlösung, Referenzen auf aufgelöste Objekte automatisch zu nilen ist wohl nicht in Aussicht.

Weil es in 99,9% der Fälle keinen Sinn macht, deshalb fände ich es auch nicht gut, wenn dafür Entwicklung betrieben wird. Entweder braucht man die Objekte auch nach der Freigabe an anderer Stelle, dann kann man Interfaces nutzen oder man braucht sie nicht, dann kann man Objektreferenzen nutzen, sollte sie aber auch nicht an Stellen zwischenspeichern, bei denen unklar ist, ob sie dem Scope entsprechen.

Eine andere Möglichkeit wäre ein Kapselinterface, das einfach nur den Zeiger auf das Objekt enthält, der für die explizite Freigabe schlicht auf nil gesetzt wird. Dann kann man von überall über dieses Interface jederzeit prüfen, ob die Freigabe bereits erfolgt ist.

Trotzdem halte ich echte Interfaces für die bessere Lösung für derlei Probleme, von ARC im mobile Compiler mal abgesehen. Solche Tricksereien um nur ja bei Objektreferenzen bleiben zu können, wenn sie eigentlich schlicht nicht zum aktuellen Anwendungsfall passen, empfinde ich nicht als saubere Lösung.

stahli 10. Okt 2013 12:35

AW: Objekte / Freigaben / Free / Nil
 
Es gibt natürlich Gründe dafür, dass es so ist wie es ist und es gibt Alternativen mit jeweils Vor- und Nachteilen.

Aber eines kann man sicher feststellen:

Neulinge (im Delphi) werden immer davon ausgehen, dass Variablen, die auf ein Objekt zeigen, nach dessen Auflösung "leer" sind.

Man kann mit der Zeit lernen, dass das nicht so ist. Aber dem Mißverständnis werden nahezu alle Delphi-Neulinge auf den Leim gehen.

Insofern fände ich eine Compiler-Magie (oder wenigstens eine optionale Standard-Problemlösung) schon interessant. Alles andere sind mehr oder wenige aufwendige und mit Nachteilen verbundene Notlösungen.
Aber ich sehe ein, dass eine automatische Lösung nicht unproblematisch zu realisieren wäre.

Furtbichler 10. Okt 2013 12:46

AW: Objekte / Freigaben / Free / Nil
 
Grauenvoll, wenn der Compiler versucht, für mich mitzudenken. Das gab es mal bei VB und die Ergebnisse waren chaotisch. Wenn Variableninhalten sich auf einmal verändern, kann das nicht gut gehen.

Wenn mehr als ein Instanzenzeiger auf ein Objekt existiert, dann dürfte es sich um einen Designfehler handeln. Würde man einen Provider zwischenschalten, gäbe es die Probleme nicht: Der Provider meldet "is weg" oder instanziiert per lazy load eine neue Instanz.

Daher ist es müßig (imho) sich darüber Gedanken zu machen, ob der Compiler diesen Lapsus reparieren soll. Na, ginge schon. Aber wenn man damit anfängt, dann müsste man auch gleich vergessene Freigaben, Ressourcenschutzblöcke usw. vom Compiler 'reparieren' lassen.

Will hier keinem zu nahe treten, aber bitte bitte, nicht noch mehr Magic.

jaenicke 10. Okt 2013 12:47

AW: Objekte / Freigaben / Free / Nil
 
Zitat:

Zitat von stahli (Beitrag 1231592)
Insofern fände ich eine Compiler-Magie (oder wenigstens eine optionale Standard-Problemlösung) schon interessant.

Was ja in Zukunft mit ARC passiert, und das wird ja vermutlich auch für Win32 irgendwann existieren.

stahli 10. Okt 2013 12:57

AW: Objekte / Freigaben / Free / Nil
 
Zitat:

Zitat von Furtbichler (Beitrag 1231596)
Will hier keinem zu nahe treten, aber bitte bitte, nicht noch mehr Magic.

Du verkennst halt, dass nicht alle (Anfänger- und Hobby-)Programmierer auf Deinem Kenntnisstand sind. Das Problem und die Hintergründe werden erst die fortgeschritteneren durchschauen.

mkinzler 10. Okt 2013 13:07

AW: Objekte / Freigaben / Free / Nil
 
Zitat:

Zitat von stahli (Beitrag 1231601)
Zitat:

Zitat von Furtbichler (Beitrag 1231596)
Will hier keinem zu nahe treten, aber bitte bitte, nicht noch mehr Magic.

Du verkennst halt, dass nicht alle (Anfänger- und Hobby-)Programmierer auf Deinem Kenntnisstand sind. Das Problem und die Hintergründe werden erst die fortgeschritteneren durchschauen.

(Objekt-)Pascal (Delphi) hat aber schon lang den Status einer Lehrsprache verlassen, was Pascal (Wirth) ursprünglich ja mal war.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:36 Uhr.
Seite 4 von 5   « Erste     234 5      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz