Delphi-PRAXiS
Seite 3 von 5     123 45      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi [XE2] Live Bindings (https://www.delphipraxis.net/163299-%5Bxe2%5D-live-bindings.html)

Stevie 27. Sep 2011 13:42

AW: [XE2] Live Bindings
 
Zitat:

Zitat von Thom (Beitrag 1126957)
Vielleicht sollte man den Aufruf korrekt durchführen?
Delphi-Quellcode:
procedure Test(i: IInterface);
begin

end;

var
  o: TInterfacedObject;
begin
  o := TInterfacedObject.Create;
  Test(o as IInterface); //<- RefCount wird automatisch erhöht
  //Objekt "lebt" noch!
end;

Gratulation, du hast den Scope nun auf die komplette Routine erweitert. Führt trotzdem dazu, dass o am Ende freigegeben wird. Mit diesem Vorgehen kann man gut RAII in Delphi umsetzen.

Zitat:

Zitat von Thom (Beitrag 1126986)
Ich habe den Eindruck, daß einige Leute gar nicht mehr ohne "Compiler-Magie" leben können und wenn diese mal versagt, kommt gleich das große Gezetere und der Hinweis darauf, wie toll das andere Sprachen hinbekommen... :lol:

Ich hab den Eindruck, dass du nicht weißt, wovon du sprichst. Klar, in dem Beispiel, hast du dem Objekt ein paar Zeilen mehr Lifetime geschenkt. Löst aber nicht das Problem, dass die Referenzzählung irgendwann unweigerlich zuschlägt. Das kann man nur durch explizites Aufrufen von _AddRef umgehen. Und dann hast du das Problem bloß verschoben, denn in dem Fall musst du entweder die Objekt Referenz so lange rumschleppen, bis du es freigeben musst, oder über einen cast des interfaces das dahinterliegende Objekt freigeben, da dass ja durch das Aushebeln der Referenzzählung durch das explizite um 1 erhöhen nicht mehr automatisch freigegeben wird. Fakt ist, ohne die Referenzzählung auszuschalten, bekommst du keine gescheite Vermischung von TInterfacedObject Derivat Referenzen und interface Referenzen hin.

Thom 27. Sep 2011 14:09

AW: [XE2] Live Bindings
 
Stevie,

ich fasse das einmal zusammen:
  • Ich stelle eine Frage, um eine - meiner Meinung nach - fragwürdige Aussage Deinerseits besser zu verstehen.
  • Daraufhin bringst Du ein Beispiel, das auf einer unkorrekten Handhabung basiert.
  • Ich weise nach, daß das von Dir angesprochene Problem zu umgehen ist.
Anstatt jetzt zu sagen bzw. zu schreiben: "Ja, das könnte man so machen, aber..." kommt
Zitat:

Zitat von Stevie (Beitrag 1127000)
Gratulation, du hast den Scope nun auf die komplette Routine erweitert. Führt trotzdem dazu, dass o am Ende freigegeben wird.
[...]
Ich hab den Eindruck, dass du nicht weißt, wovon du sprichst.

"o am Ende freigegeben wird"? Aha... Wo in Deinem Beispiel wird die Verwendung des Objektes o nach Beendigung der Prozedur außerhalb beschrieben? Daß Interfaces bzw. Objekte mit einem Interface automatisch freigegeben werden, wenn die Referenzzählung bei Null angekommen ist, ist ja gerade eine grundlegende Idee dieser Technik. Will man solche Objekte erhalten, muß man lediglich den Referenzzähler explizit erhöhen, falls das eben nicht durch "Compiler-Magie" erledigt wird.

Zitat:

Fakt ist, ohne die Referenzzählung auszuschalten, bekommst du keine gescheite Vermischung von TInterfacedObject Derivat Referenzen und interface Referenzen hin.
Ich schon - wenn Du's nicht hinbekommst, solltes Du Dich fragen, weshalb...

Vielen Dank für diese eindrucksvolle Demonstration Deiner Fachkenntnisse und deiner Überheblichkeit. :thumb: :lol:

mquadrat 27. Sep 2011 16:22

AW: [XE2] Live Bindings
 
So, jetzt entspannen wir uns alle erst mal.


Ich finde es durchaus unintuitiv (von mir aus auch nervig und fehlerträchtig, wenn die Wörter besser passen sollten) wenn ein Objekt einer Klasse explizit in ein Interface gecastet werden muss, obwohl die Klasse ansich das Interface bereits bestätigt hat. Der korrekte Weg ist es sicher, aber gefallen muss es mir deshalb ja noch nicht ;) Und die Menge der Threads und Blog-Posts zu diesem Thema zeigt imho durchaus, dass es unintuitiv ist.

Stevie 27. Sep 2011 16:37

AW: [XE2] Live Bindings
 
Der erste, der in diesem Thread "überheblich" daher kam (was ich im übrigens nicht so aufgefasst habe, ich bin da relativ unempfindlich), warst du mit folgender Aussage:
Zitat:

Zitat von Thom (Beitrag 1126986)
Ich habe den Eindruck, daß einige Leute gar nicht mehr ohne "Compiler-Magie" leben können und wenn diese mal versagt, kommt gleich das große Gezetere und der Hinweis darauf, wie toll das andere Sprachen hinbekommen... :lol:

Nebenbei versagt in meinem Beispiel überhaupt keine "Compiler-Magie". Dein Softcast führt nur zu einem weiteren AddRef und Release (schau in den Debugger, wenn du mir nicht glaubst), welche den Lifecycle des Objekts auf den gesamten Prozedurbereich ausdehnen, anstatt nur auf den Call der Test Prozedur. Ähnliches passiert, wenn man eine Funktion hat, die eine Referenz zurückliefert, man diese aber nicht irgendwo speichert.

Außerdem war mein Beispiel das Minimalste, um zu zeigen, was passiert, wenn man Objektreferenz und Interface Referenz vermischt - und ich bin davon ausgegangen, dass man das auf ein komplexeres Szenario (Objekt wird außerhalb dieser Routine weiterverwendet) abstrahieren kann.

Eventuell überzeugt dich jemand, der mehr Ahnung von Delphi hat (Zweiter Absatz: "That basically means that mixing object references and interface references is dodgy". Und auch andere Delphi Entwickler sind schon in diese Falle getappt und es wird auch regelmäßig auf die Gefahren beim Vermischen (siehe die beiden letzten Absätze in der accepted answer) von beidem hingewiesen.

Falls das Erklären dieses fundierten Sachverhalts als Überheblichkeit missinterpretiert werden konnte, entschuldige ich mich dafür.

Union 28. Sep 2011 08:17

AW: [XE2] Live Bindings
 
Ich hab da mal eine mehr praxisorientierte Frage: Wie führe ich eigene Methoden und Konverter sinnvoll ein und wie konfiguriere ich diese, dass sie in der Topologie Vorrang haben?

Beispielsweise habe ich ein Edit an eine Property eines anderen Controls gebunden. Wird er Inhalt des Edits gelöscht und ein Notify ausgeführt, so knallt es natürlich mit einem EConversionError, weil ja folgendes passiert:
Delphi-Quellcode:
StrToInt('')
Ich könnte das natürlich ganz oben beim Notifier individuell abfangen, nur brauche ich dann keine LiveBindings mehr ;)

Stevie 28. Sep 2011 10:58

AW: [XE2] Live Bindings
 
DSharp hat durch einige Hilfsmethoden für TValue Konvertierungen für nahezu alle Standard Typen.

Bei den LiveBindings würde ich an dieser Stelle StrToIntDef benutzen.

Union 28. Sep 2011 11:03

AW: [XE2] Live Bindings
 
Spassvogel ;) D# ist ja bestimmt toll, aber mir geht es um XE2 (wie ja im Titel auch steht). Dass ich StrToIntDef benutzen sollte ist mir auch klar. Nur nicht wie ich das in das Binding reinbekomme. Und wie ich es in der Topologie steuere damit die richtige Methode verwendet wird.

Stevie 28. Sep 2011 11:09

AW: [XE2] Live Bindings
 
Also wenn ich über ne TBindExpression nen Edit und ne SpinEdit verbinde, brauch ich garnix konvertieren, wenn das Edit leer ist, wird 0 ins SpinEdit geschrieben (XE2 Update 1).

P.S. Für dich dürfte System.Bindings.Outputs.RegisterBasicOutputConvert ers interessant zum Anschauen sein. Dort werden die ganzen Default Converter gebaut.

Union 28. Sep 2011 11:26

AW: [XE2] Live Bindings
 
Ich habe ein TLabel.Top an TSpinEdit.Value gebunden. Wenn ich den Spinedit-Inhalt dann mit Entf komplett lösche, gibt es intern eine Exception. Die wird natürlich nur angezeigt wenn ich debugge... Funktional ist alles in Ordnung, das Top hat dann 0. Jetz tstell ich mir mal vor ich teste eine Anwendung wo ALLES nur noch über Livebindings läüft - das wird dann richtig eklig.
Code:
7c812afb kernel32.RaiseException + 0x52
System.SysUtils.ConvertErrorFmt($40FAB0,(...))
System.SysUtils.StrToInt(???)
Vcl.Samples.Spin.TSpinEdit.GetValue
System.Rtti.RawInvoke(???,???)
System.Rtti.Invoke($66BFA0,((($66AAEC, Pointer($67A878) as IValueData, 112, 51824, 27249264, $19FCA70, TClass($19FCA70), 112, -13712, 27249264, 5,86978591229431e-38, 1,34629252168586e-316, 0,00000000009933e-4933, 27249264, 2724,9264, 27249264, 27249264, ($19FCA70, nil), $19FCA70))),???,$4010A0,False)
System.Rtti.TRttiInstanceProperty.DoGetValue(???)
System.Rtti.TRttiProperty.GetValue(???)
Und meine weitere Frage war ja, wie ich eigene Methoden da reinbekomme. [edit]Ich gucks mal an. Auf die embwiki kann ich ja wahrscheinlich noch etwas warten[/edit]

stahli 28. Sep 2011 11:36

AW: [XE2] Live Bindings
 
etwas OT:

Zitat:

Zitat von Union (Beitrag 1127213)
Wenn ich den Spinedit-Inhalt dann mit Entf komplett lösche, gibt es intern eine Exception. Die wird natürlich nur angezeigt wenn ich debugge... Funktional ist alles in Ordnung, das Top hat dann 0.

Mich hat das auch schon mehrfach gestört, dass im SpinEdit nicht explizit auf '' getestet und 0 zugewiesen wird (oder alternativ StrToIntDef verwendet wird). Ich konnte das dann irgendwie immer noch vorher abfangen, aber ein solch unnötiges Problem ... ärgerlich.

EDIT: Aber Dein genanntes Problem dürfte sich auf das SpinEdit beschränken - oder?
Sonst hört sich das Binding ja ganz gut an. Vielleicht solltest Du für den ernsthaften Einsatz ein NullabelSpinEdit ableiten, das diesen Fehler intern vermeidet.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:29 Uhr.
Seite 3 von 5     123 45      

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