AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Weak-TList ?

Ein Thema von himitsu · begonnen am 26. Feb 2015 · letzter Beitrag vom 11. Mär 2015
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#1

Weak-TList ?

  Alt 26. Feb 2015, 00:09
Delphi-Version: XE7
Tachchen.

Delphi-Quellcode:
var
  [Weak] Variable: IInterface;
  [Weak] Liste: TList<IInterface>;
  Liste: TList<[Weak] IInterface>; // geht nicht - Error-Insight und Compiler sagen nein
Die Variable wäre jetzt ohne Referenzzählung, im NextGen-Compiler,
aber wie definiert man eigentlich eine Liste mit Weak-Referenzen?

Bei [Weak] Liste: TList<IInterface>; ist natürlich (nur?) die Liste-Variable ohne Referenzzählung, aber nicht der Listeninhalt. So würde ich die OH verstehen tun.

Kann es leider nicht ausprobieren und die Compiler sind diesbezüglich echt doof und geben keinerlei Meldungen/Fehlermeldungen, ob Attribute richtig sind oder ob sie es nicht sind.
Nichtmal bei Denen, die den Compiler und den erzeugten Code/Typen/RTTI selber betreffen.

Die Hilfe sagt natürlich rein garnichts, zu [Weak] bei Typen. Und in der Hilfe zum WeakAttribute steht wirklich GARNICHTS (nur der bekannte nichtssagende Schrott).

Delphi-Quellcode:
type
  IWeakInterface = [Weak] IInterface; // Hier sträubt sich das Error-Insight und der Compiler.
  [Weak] IWeakInterface = IInterface; // Geht das?
  [Weak] IWeakInterface = type IInterface; // Und ist das richtig?

var
  Liste: TList<IWeakInterface>;
$2B or not $2B
  Mit Zitat antworten Zitat
Daniel
(Co-Admin)

Registriert seit: 30. Mai 2002
Ort: Hamburg
13.920 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Weak-TList ?

  Alt 26. Feb 2015, 07:55
aber wie definiert man eigentlich eine Liste mit Weak-Referenzen?
Eigene Listen-Klasse mit eigenem Listen-Objekt, welches seinerseits die weak-Referenz auf Deine Interfaces beinhaltet und entsprechend kommunizieren kann, ob da noch etwas ist oder nicht.
Daniel R. Wolf
mit Grüßen aus Hamburg
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.027 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#3

AW: Weak-TList ?

  Alt 26. Feb 2015, 08:39
Delphi-Quellcode:
program WeakRefListTests;

uses
  TestFramework,
  TestInsight.DUnit,
  Spring,
  Spring.Collections;

type
  TWeakRefListTest = class(TTestCase)
  published
    procedure ListDoesNotKeepStrongReference;
  end;

  IRefCounted = interface
    function GetRefCount: Integer;
    property RefCount: Integer read GetRefCount;
  end;

  TRefCounted = class(TInterfacedObject, IRefCounted);

procedure TWeakRefListTest.ListDoesNotKeepStrongReference;
var
  sut: IList<WeakReference<IRefCounted>>;
  ref: IRefCounted;
begin
  sut := TCollections.CreateList<WeakReference<IRefCounted>>;
  ref := TRefCounted.Create;
  sut.Add(ref);
  CheckEquals(1, ref.RefCount);
  ref := nil;
  CheckFalse(sut[0].IsAlive);
  ref := sut[0];
  CheckNull(ref);
end;

begin
  RegisterTest(TWeakRefListTest.Suite);
  RunRegisteredTests();
end.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#4

AW: Weak-TList ?

  Alt 26. Feb 2015, 10:44
Nja, dachte daß Delphi sowas auch selber kann.

Die [Weak]-Referenzen werden doch auch nicht auf nil gesetzt, sondern sind dann einfach nur "ungültige" Zeiger.
Aber das Problem gibt es nicht, da sich die Interfaces selber überall raus löschen, wenn sie freigegeben werden. (die kennen die Gegenseite, da sie selber eine gezählte Referenz besitzen, oder sie kennen wen, der den kennt)

Nur dürfen diese Referenzen halt nicht gezählt werden, damit sie sich freigeben können.

Für einzelne Variablen und Felder geht das Einfach, aber wie man das für Listen/Arrays deklariert, ist nirgendwo beschrieben, obwohl es irgendwie gehen soll.
$2B or not $2B
  Mit Zitat antworten Zitat
Daniel
(Co-Admin)

Registriert seit: 30. Mai 2002
Ort: Hamburg
13.920 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Weak-TList ?

  Alt 26. Feb 2015, 10:46
Die [Weak]-Referenzen werden doch auch nicht auf nil gesetzt, sondern sind dann einfach nur "ungültige" Zeiger.
ehm. Na doch. Das ist doch gerade der Witz an einem Weak-Pointer. Der kennt nur zwei stabile Zustände: "Gültige Referenz" oder "NIL".
Daniel R. Wolf
mit Grüßen aus Hamburg
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Weak-TList ?

  Alt 26. Feb 2015, 10:48
Dazu hatten wir schon was

http://www.delphipraxis.net/183253-a...nicht-arc.html
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#7

AW: Weak-TList ?

  Alt 26. Feb 2015, 10:54
Im ARC wollte ich mal versuchen das möglichst alles "nativ" zu belassen.
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: Weak-TList ?

  Alt 26. Feb 2015, 11:03
Im ARC wollte ich mal versuchen das möglichst alles "nativ" zu belassen.
Was hat das mit "nativ" zu tun?

Hier mal ein Beispiel, wo so eine WeakRef-Record für ARC sinnvoll verwendet werden kann:
Delphi-Quellcode:
function Foo( const ABitmap : TBitmap ):ITask;
var
  LBitmapRef: WeakRef<TBitmap>;
begin
  // WeakRef auf Bitmap
  LBitmapRef := ABitmap;
  Result := TTask.Create(
    procedure
    var
      LBitmap : TBitmap;
    begin
      // StrongRef auf Bitmap, damit die bis zum Ende des Tasks überlebt, wenn es die noch gibt :o)
      LBitmap := LBitmapRef;
      // Wenn Bitmap schon weg ist, dann raus hier
      if not Assigned( LBitmap ) then Exit;
      // Now work on Bitmap
      
    end );
end;
Du erzeugst also einen Task, der irgendwann gestartet werden soll. Die übergebene Bitmap kann aber bis zum echten Start schon wieder verschwunden sein. Ist die Bitmap beim Starten aber nicht verschwunden, dann wird im Task wieder eine Strong-Ref auf Bitmap gemacht und schon lebt die Referenz bis zum Ende des Tasks.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (26. Feb 2015 um 11:05 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#9

AW: Weak-TList ?

  Alt 26. Feb 2015, 11:31
Mit "nativ" meinte ich "Nur mit den Mitteln dessen, was Delphi selber kann", also ohne Fremdkomponenten und möglichst ohne viel selbst zu basteln.

Die ersten Beiden sollten schon funktionieren (zumindestens im NextGen/WEAKINTREF),
Delphi-Quellcode:
type
  TParent = class(TInterfacedObject, IParent)
    FChild: IChild;
  end;

  TChild = class(TInterfacedObject, IChild)
    [Weak] FParent: IParent;
  end;
Delphi-Quellcode:
type
  TParent = class(TInterfacedObject, IParent)
    FChilds: TList<IChild>;
  end;

  TChild = class(TInterfacedObject, IChild)
    [Weak] FParent: IParent;
  end;
aber hier hängt es, also wie man das genau "definiert".
Delphi-Quellcode:
type
  TParent = class(TInterfacedObject, IParent)
    FLink: ILink;
  end;

  TLink = class(TInterfacedObject, ILink)
    FParents: TList<[Weak] IParent>;
  end;
Wenn Delphi das dann in den nächsten 20 Jahren endlich mal in allen Compileren richtig drin hat,
(k.A. warum man [Weak] für Interfaces nicht überall eingebaut hat )
dann wäre jetzt kein weiterer Code mehr nötig.
$2B or not $2B

Geändert von himitsu (26. Feb 2015 um 11:35 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#10

AW: Weak-TList ?

  Alt 11. Mär 2015, 01:45
Ich hatte nun 'ne ganze Weile versucht damit einen "ordentlichen" Code hinzubekommen, welcher auf allen Platformen richtig funktioniert.

Also mit den aktuellen/alten Möglichkeiten der Delphi-Compiler [Weak] , [Unsafe] , [Ref] und [Volatile] .
Den Blick in OH/Dokwiki könnt ihr vergessen, denn bei den Attributen ist nichts zu finden, aber es gibt einen anderen etwas versteckteren Hilfe-Eintrag dazu. (verlinken können die sowas natürlich nicht)



Fazit: Alles Mist und ich caste die Rückreferenzen nun überall nur noch selbst als Pointer.

Für "einfache" 1:1-Kreuzverlinkungen mit einfachen Variablen ist [Weak] und [Unsafe] im ARC allerdings ganz praktisch, auch wenn es keine richtig nicht-referenzgezählten Variablen gibt, wo es absolut keine Behandlung von Referenzen gibt.
Aber sobald Listen oder kompliziertere n:n-Verlinkungen ins Spiel kommen, ist es nahezu unmöglich einen "nativen" Code zu schreiben, der wirklich überall läuft und das auch nur mit ausreichenden IFDEFs oder über Fremdkomponenten.

Wenn ich bissl aufgeräumt und alles nochmal durchgelesen hab, dann werde ich demnächst mal meine Testanwendung/Testcode/Artikel für diese beiden "schwachen Referenzen" hochladen.

Leider gibt es [Weak] , [Unsave] und [NoRefCount] nicht in allen Platformen.
https://quality.embarcadero.com/browse/RSP-10135
Im Grunde ist das der Grund, warum ich einige Komponenten nun komplett und umständlich (da doppelte Deklarationen usw.) auf Interfaces umstelle, damit sie überall funktionieren und überall gleich benutzbar sind.
Grade bei den Interfaces gibt es nun, dank [Weak] und AutoRefCount (für interne Objekte), dennoch standardmäßig kein gleiches Verhalten, außer man sorgt selber auf brutalste Weise dafür.
(nur Interfaces ohne irgendwelche Objektreferenzen und ohne schwachen Referenzen arbeiten wirklich überall gleich)
$2B or not $2B

Geändert von himitsu (11. Mär 2015 um 02:02 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:12 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz