![]() |
Problem mit ARC unter iOS?
Hallo!
Ich programmiere eine iOS-App unter Verwendung der ![]() Gibt es eine verlässliche Methode, mit der man überprüfen kann, ob dynamisch erzeugte Controls auf einer dynamisch erzeugten View von ARC freigegeben werden? |
AW: Problem mit ARC unter iOS?
Wie gibts Du die Controls denn frei? Du kannst mit den Instruments von xCode verfolgen was genau wann passiert (Memory).
|
AW: Problem mit ARC unter iOS?
Ich setze am Ende der Methode (in der die Controls alle deklariert und erstellt werden) alle Controls auf nil und gehe davon aus, dass ARC das Control bei der nächsten Gelegenheit wieder freigibt.
|
AW: Problem mit ARC unter iOS?
Wie Darlo schon geschrieben hat, lässt sich das am einfachsten mit Instruments verfolgen, da kann man sich u.a. die komplette Struktur der noch vorhandenen Objekte anzeigen lassen.
Ein Objekt auf nil zu setzen reicht bei ARC nicht unbedingt. Solange noch irgendwelche Verweise auf das Objekt vorhanden sind, wird es nicht freigegeben. Ich habe mir dazu auch zu Debugging-Zwecken eine eigene Routine erstellt:
Code:
Die ist ziemlich nützlich, auch um Leaks in den Delphi-Komponenten zu finden.
procedure TryFree(const AUnitName: String; const AObj: TObject);
begin if not Assigned(AObj) then Exit; {$IFDEF AUTOREFCOUNT} if AObj.RefCount > 1 then begin OutputDebugStrFmt('[[%s]] %s.RefCount=%d', [AUnitName, AObj.QualifiedClassName, AObj.RefCount]); AObj.DisposeOf; end; {$ELSE} AObj.Free; {$ENDIF AUTOREFCOUNT} end; |
AW: Problem mit ARC unter iOS?
Zitat:
Zitat:
|
AW: Problem mit ARC unter iOS?
Man braucht keine Unterscheidung zu machen.
Delphi-Quellcode:
testet selber auf
TObject.DisposeOf
Delphi-Quellcode:
und ruft den Destructor auf (egal ob ARC oder nicht).
nil
Delphi-Quellcode:
testet selber auf
TObject.Free
Delphi-Quellcode:
und ruft den Destructor auf (nur bei NICHT-ARC)
nil
Will man also eine Komponente ins Jenseits befördern, nimmt man generell
Delphi-Quellcode:
.
DisposeOf
Genauso mit Streams und sonstigen Instanzen, die noch Ressourcen halten, die man jetzt gesichert freigeben möchte. Für den Rest nimmt man
Delphi-Quellcode:
oder
Free
Delphi-Quellcode:
.
FreeAndNil
|
AW: Problem mit ARC unter iOS?
Zitat:
Was passiert, wenn auf dem mit DisposeOf gekillten Control andere Controls liegen, die es als Parent referenzieren? |
AW: Problem mit ARC unter iOS?
Wird eine
Delphi-Quellcode:
Instanz zerstört werden auch alle Components zerstört.
TComponent
Wird eine
Delphi-Quellcode:
Instanz zerstört werden auch alle Children zerstört.
TWinControl
Wird eine
Delphi-Quellcode:
Instanz zerstört werden auch alle Children zerstört.
TFmxObject
Delphi-Quellcode:
zerstört ohne Wenn und Aber (ARC oder nicht).
TObject.DisposeOf
Einfache und alte Regel ... nur das mit dem
Delphi-Quellcode:
ist neu.
DisposeOf
|
AW: Problem mit ARC unter iOS?
Zitat:
|
AW: Problem mit ARC unter iOS?
Zitat:
|
AW: Problem mit ARC unter iOS?
Und was sagt der Debugger?
Also WO stürzt es denn ab? Bei TComponents gibt es auch noch Verbindungen zwischen den Controls, welche Referenzen darstellen und somit die Komponenten am Leben erhalten. Und wenn du dir wirklich nicht sicher bist, ob etwas freigegeben wird, dann bau z.B. eine MessageBox/Logging in den Destructor und fertig. Und warum verdammt nochmal ist man auf diese bescheuerte Idee mit dem DisposeOf gekommen und hat nicht einfach auch im ARC mit Free das "wirklich" freigeben können? Also das aus DisposeOf ins Free eingebaut. |
AW: Problem mit ARC unter iOS?
![]() ![]() ![]() ![]() ![]() Darum gelten für ein
Delphi-Quellcode:
die Regeln für
TControl
Delphi-Quellcode:
und
TComponent
Delphi-Quellcode:
:stupid:
TFmxObject
Weil unter ARC die Uhren anders ticken braucht man eine andere Strategie was den Destructor angeht. Der Destructor wird unter ARC automatisch aufgerufen, wenn der RefCount auf 0 geht (keiner will mehr mit der Instanz spielen). Würde jetzt mit
Delphi-Quellcode:
unter ARC auch der Destructor aufgerufen, dann würde dieser mindestens zweimal aufgerufen:
Free
Delphi-Quellcode:
Ist das auch jedem bewusst? Denn das wäre ein anderes Verhalten als man es gewohnt ist.
var
foo: TFoo; foo.Free; // Destructor wird aufgerufen (ohne ARC) foo := nil; // Destructor wird aufgerufen (mit ARC) Darum gibt es die
Delphi-Quellcode:
Methode, weil ich als Programmierer damit (hoffentlich) ganz bewusst den Doppelaufruf des Destructors akzeptiere.
DisposeOf
Delphi-Quellcode:
Im Destructor kann man noch den Status
var
foo: TFoo; foo.DisposeOf; // Destructor wird aufgerufen (immer) foo := nil; // Destructor wird aufgerufen (ARC) ![]()
Delphi-Quellcode:
Wer sieht das Problem?
destructor TFoo.Destroy;
begin CloseHandle( FHandle ); inherited; end; Unter ARC könnte ich damit ein Handle schliessen, was ich aber gar nicht schliessen möchte. Der Destructor sollte so aussehen
Delphi-Quellcode:
denn nur so wird das Freigeben des Handle auch nur einmal ausgeführt.
destructor TFoo.Destroy;
begin if not Disposed then begin CloseHandle( FHandle ); end; inherited; end; PS Die Beispiele in der Dokumentation von Emba beinhalten einen Fehler, denn die Eigenschaft ![]()
Delphi-Quellcode:
und kann von aussen gar nicht abgefragt werden :roll:
protected
|
AW: Problem mit ARC unter iOS?
[QUOTE=romber;1327772]
Zitat:
|
AW: Problem mit ARC unter iOS?
Man hätte aber das "abweichende" Verhalten anders benennen können, anstatt das Standardverhalten zu ändern.
Von mir aus auch einen WirklichGenauJetztFreigeben-Parameter beim Free mit dran (Default False?) Halbwegs abwärtskompatiblen Code kann man so schon lange vergessen und Crossplattform ist auch nicht grade einfach. |
AW: Problem mit ARC unter iOS?
Zitat:
Mit
Delphi-Quellcode:
wird der Destructor nur einmal durchlaufen. Da hat sich nichts geändert.
Free
Was ist denn gefährlicher?
Man muss sich vor Augen halten, was eine Methode denn wirklich macht/bedeutet, dann ist so ein Paradigmenwechsel auch nicht mehr so schwer. Grundsätzlich wäre ich aber für die generelle Einführung von ARC auf jeder Plattform. Dieser Mischmasch bei einer Multiplattform Anwendung bringt einen eher um den Verstand. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:49 Uhr. |
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