Die starke schwache Referenz und ihre Zählung

Auch diesmal wieder eine Übersetzung eines XojoBlog-Beitrags, diesmal vom spanischen Kollegen Javier Rodriguez – aber auch eine Antwort auf eine mich kürzlich erreicht habende Frage zum modernisierten REALife-Projekt. Die drehte sich darum, warum ich das Fenster als Property der Board-Klasse (dem „Spielbrett“ des Game of Life-Programms) so kompliziert in eine WeakRef verpacke, anstatt es einfach als Window zu speichern.

Nun, bei diesem Beispielprogramm ist es eigentlich nicht nötig. Es besteht nur aus einem Fenster, und wird es geschlossen, dann soll das Programm auch beendet werden. Damit wird alles im Speicher freigegeben.

Ich versuche aber nach bestem Wissen und Gewissen, gute Programmierpraxis zu vermitteln. Und in einem komplexeren Programm mag das direkte Ablegen des Fensters als Property in einer unabhängigen Klasse zu einem Zirkelbezug führen:

Sie wissen ja, dass Xojo seit Jahr und Tag ARC zur Speicherverwaltung verwendet, Automatic Reference Counting oder zu gut Deutsch Referenzzählung. Das bedeutet, dass ein Objekt so lange im Speicher lebendig gehalten wird, wie es von mindestens einem anderen Objekt referenziert wird – also z.B. von der Methode, in der es referenziert wird.

Das kann verschiedene Auswirkungen haben: Von gar keiner wahrnehmbaren über Memory Leaks bis hin zu Abstürzen, wenn nämlich durch unglückliche Umstände das Objekt noch da zu sein scheint (es also nicht Nil ist), aber die Daten dahinter gelöscht wurden. Letzteres hat Javier in einem Beispielprojekt verdeutlicht, das ich hier, da momentan im Original auf einer Dropbox liegend, deren Public-Ordner demnächst vom Hersteller abgeschafft wird, zum Spielen bereithalte.

Drücken Sie hier auf den „Go“-Button, wird ein Timer gestartet, der alle geöffneten Fenster des Programms später wieder schließt. Zugleich aber wird ein Objekt der Klasse WorkingClass erzeugt, das das Textarea des ersten Fensters direkt referenziert und ein weiteres Fenster modal öffnet. Die weitere Ausführung der Work-Methode, die in das TextArea schreiben will, wird also angehalten, bis das modale Fenster geschlossen wurde.

Dummerweise ist dieses dann eigentlich nicht mehr vorhanden – und auch das Textarea nicht mehr wirklich. Es wird weiterhin als Property von WorkingClass referenziert und ist daher beim Test nicht Nil. Seine eigentlichen Daten sind aber durch das Schließen des ersten Fensters mit gelöscht worden, weshalb sich das Programm sehr unelegant verabschiedet:

SigSev.png

Die Exception EXC_BAD_ACCESS (SIGSEV) deutet darauf hin, dass das Programm eine Objektstruktur im Speicher manipulieren wollte (die des TextAreas), aber keine mehr vorgefunden hat.

Tja, und um solche Unannehmlichkeiten zu vermeiden, gibt es die WeakRef – die schwache Referenz. Sie ermöglicht es, ein Objekt zu referenzieren, ohne dessen Referenzzählung zu erhöhen – sie hält das Objekt also nicht im Speicher fest.

Wandeln Sie dazu einfach die Property SourceControl in eine Computed Property um, machen Sie das automatisch erzeugte mSourceControl zu einer Xojo.Core.WeakRef, und die Computed Property bestücken Sie wie folgt:

Public Property sourceControl as TextArea
 Get
  if msourceControl <> nil then return TextArea(msourceControl.value)
 End Get

 Set
  msourceControl = xojo.core.Weakref.Create(value)
 End Set
End Property

Wenn Sie das Programm nun laufen lassen: Viel besser, oder?

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s