Aaron Fischer Ingenieur, Vater, Heimwerker, Problemlöser

Programmiersprachen

Pattern Matching & Destructing in eLisp vor 5 Jahren

In Clojure stößt man unweigerlich auf Destructing, was man -- einmal verstanden -- nicht mehr missen will. Dieses Sprachfeature macht die Zuweisung von Daten in einer Datenstruktur in Variablen sehr einfach. Dabei werden Muster mit Platzhaltern definiert, auf die dann die eigentliche Datenstruktur aufgelegt wird. Hört sich kompliziert an, ist es aber nicht.

Destructing in Clojure vor 8 Jahren

Destructing (auch Abstract Structural Binding genannt) ist eines von vielen Features in Clojure, die die Sprache für mich so unglaublich elegant und schön machen. Wer noch nie mit Clojure programmiert hat, sollte jetzt genau aufpassen :) (Achtung: Ich rede hier von Variablen, doch korrekterweise sind es lexikalische Bindungen. Alle Bindungen in Clojure sind unveränderbar (immutable), also keine Variablen. Dennoch ist es für das Verständnis einfacher sie Variablen zu nennen.)

Memory Management in Objective-C über 13 Jahre

Die meisten modernen Programmiersprachen haben eine dynamische Speicherverwaltung, die von der VM oder dem Interpreter gesteuert wird. Manuelle Speicherreservierung (malloc) und Freigabe des nicht mehr verwendeten Speichers (free) sieht man heutzutage fast nur noch in historischen Projekten und an Stellen an denen der Speicher knapp ist.

In Objective-C wird dem Programmierer die Wahl gelassen, ob er den Speicher selbst verwalten oder es dem Garbage Collector überlassen will. Die Programme können sogar so geschrieben werden, dass sie beide Modis unterstützen um Abwärtskompatibel zu bleiben. (Bspw. um eine Library auf dem iPhone und in einer Desktop-Anwendung zu nutzen)

Die Einstellung wird in XCode mit einem Doppelklick auf das Build-Target erreicht:

Garbage Collector Schalter

Wird der Garbage Collector ausgestellt, ist der Programmierer selbst für die Speicherallokation zuständig. Objective-C ähnelt etwas dem der Java VM. Jedes Objekt hält intern einen Referenzzähler (retain-count genannt), der angibt, wie viele andere Objekte dieses Objekt benötigen. Sinkt dieser Zähler auf 0, wird das Objekt aus dem Speicher entfernt.

Um den retain-counter zu inkrementieren, muss eine retain-Nachricht an das Objekt gesendet werden. Diese kann von allen Objekten entgegengenommen werden, die von NSObject abgeleitet wurden, also so gut wie alle. Zum Dekrementieren wird release verwendet. Ein kleines Beispiel:

NSArray *users = [[NSArray alloc] init]; // retain-count = 1
// Do some stuff
[users release] // retain-count = 0

Hierbei gibt es zwei wichtige Faustregeln (beide aus Memory Management in Cocoa entnommen):

You should never release an object that you have not retained or created.

und

Make sure that there are as many release or autorelease messages sent to objects as there are alloc, copy, mutableCopy, or retain messages sent. In other words, make sure that the code you write is balanced.

Interessant wird es, sobald Objekte an andere Objekte gesendet werden. Hier hat das ursprüngliche Objekt keine Kontrolle mehr darüber, was mit dem Objekt passiert, und kann es deshalb auch nicht mehr sauber aus dem Speicher räumen.

Hier kommt der Autorelease Pool ins Spiel: In ihm lassen sich zur Speicherfreigabe vorgesehene Objekte vormerken, um dann an einer geeigneten Stelle die release-Nachrichten zu verschicken. Dies ist aufs Erste Mal nicht so ganz einleuchtend, deshalb wieder ein Beispiel:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSNumber *fourtytwo = [NSNumber numberWithFloat:42];
// Some stuff ...
[pool release];

In der ersten Zeile wird der Autorelease Pool erstellt. Er enthält alle Referenzen zu den Objekten, die aus dem Speicher entfernt werden können. Auch diejenigen, die von anderen Methoden erzeugt werden. In diesem Fall ist das das NSNumber-Objekt, das nicht über den Standard-Konstruktor init erzeugt wurde, also nicht in der aktuellen Methode sondern an einem anderen Ort. Da wir in unserer aktuellen Methode nicht wissen, ob das NSNumber-Objekt noch anderweitig verwendet wird (da wir es ja nicht direkt erstellt haben), können wir es auch nicht mit [fourtytwo release] bedenkenlos aus dem Ram löschen. Dafür ist der Autorelease Pool zuständig. Sobald das NSNumber-Objekt an keiner Stelle mehr verwendet wird, landet es in einem AutoreleasePool. Rufen wir dann [pool release] auf, wird an allen enthaltenen Objekten die release-Nachricht gesendet, welche einen release-count von 0 vorweisen.

Wenn der Speicher manuell verwaltet wird, treten meist ziemlich hässliche Fehler auf, die sehr schwer zu finden sind. Speicherlecks sind tückische Biester, die sporadisch auftauchen und nicht selten lange unentdeckt bleiben. Um dem entgegenzuwirken und das Debugging nach einem SegFault etwas einfacher zu machen, können diese beiden Optionen gesetzt werden (Doppelklick aufs Executable in XCode):

Donald Knuth, der Meister der Lyrik über 14 Jahre

Donald E. Knuth ist die lebende Legende im Softwareumfeld. Er widmet schon über Jahrzehnte hinweg sein Leben der Forschung und der formalen Beschreibung von Algorithmen. Sein still in progress Band Art of Computer Programming ist wahrlich ein Meisterwerk. Interessant ist aber, dass sich die wenigsten Informatiker an dieses monströse Werk wagen. Er ist auch der Auffassung, dass Programmcode mit derselben Sorgfalt verfasst werden sollten wie literarische Texte. Dokumentation und Code sollten vereint sein. weiter ...

Active Browsing, Teil 1 fast 15 Jahre

Wer bei meinem Vortrag mit dem Titel Fix the web with Greasemonkey dabei war, weiß was gemeint ist. Für alle anderen ein kleiner Abriss: Das Web liefert uns aufbereitete Daten in einer Form, die der Ersteller festlegt. Oft ist es aber so, dass man nur an einer bestimmten Information interessiert ist und alles andere am liebsten ausblenden würde oder auf eine andere Art und Weise dargestellt bekommen möchte. Mechanismen, die dazu beitragen, die Informationen so darzustellen, wie es einem selbst am besten gefällt, nennt man Active Browsing. Mittlerweile gibt es einige Tools, um sich das Surfen etwas zu personalisieren und nach den eigenen Wünschen zu formen. weiter ...

Active Browsing, Teil 2 fast 15 Jahre

Im letzten Beitrag habe ich über Active Browsing geschrieben und der Mächtigkeit, die jeder User im Grunde hat, diese aber nicht nutzt. Wir wollen uns nun das Leben mit ein paar Zeilen Code vereinfachen.

Um ruby-libnotify und mechanize nutzen zu können, müssen sie zuerst installiert werden. Bei Mechanize ist das kein Problem, da es schon als rubygem vorliegt. Ein simples gem install mechanize installiert das Paket, inklusive nokogiri für das Parsen der Webseiten. Bei ruby-libnotify muss man selbst Hand anlegen und mit dem Dreischritt ruby extconf.rb && make && make install das Paket zusammenbauen und installieren. Wer das Paket libopenssl-ruby noch nicht installiert hat, sollte das zuvor erledigen. weiter ...

XML als DSL für GUIs fast 16 Jahre

Ich bin schon seit vielen Jahren auf der Suche nach einer Möglichkeit, GUIs mit einem grafischen Editor zu erstellen und trotzdem nicht von einer IDE abhängig zu sein. Ich wünschte mir ein Tool, mit dem ich die GUI erstellen könnte und als Output eine (XML)-Beschreibung der erstellten Oberfläche erhalten würde.

AWT/Swing in Java war mir schon immer zuwider (mit und ohne GUI-Builder). Der (live) generierte Java-Code ist meist dermaßen hässlich und nachträglich unwartbar, so dass ich meist wieder selbst Hand angelegt habe und die GUI-Elemente selbst platziert habe. Dass es hier noch keine vernünftige Lösung gibt, wundert mich immer wieder. weiter ...