Die Einführung des iOS 5 SDKs und der dazugehörigen Entwicklungsumgebung XCode 4.2.x ist auch gleichzeitig als Geburtsstunde des neuen Clang 3.0 Kompilers (llvm 3.0) zu betrachten. Durch den Einsatz des neuen Standard-Kompilers hat sich Apple zugleich auch vom bisher jahrelang mitgelieferten GCC-Kompilers endgültig verabschiedet. Ein Meilenstein für Apple, die Programmiersprache Objective-C, für die Features von XCode und nicht zuletzt für die iOS-Entwickler (auch MacOS Entwickler). Ohne auf all die zahlreichen Neuerungen einzugehen ist die für Entwickler herausragendste Neuerung zweifelsohne ARC.

Kurz beschrieben kann man über ARC (Automatic Reference Counting) sagen, dass man sich als Entwickler nun nicht mehr selbst um ein sauberes Memory-Management kümmern muss,

sondern das System (Kompiler+Objective-C-Runtime) die Aufräumarbeiten der nicht mehr benötigten eigenen Objekte übernimmt. Bisher musste der Entwickler ein stets ausbalanciertes Lifecycle-Management seiner Objekte durch Aufruf der retain/release/autorelease Methoden an den richtigen Code-Stellen manuell selbst bewältigen – somit wurde diese bisherige Variante des Memory-Managements nachträglich als MRC (Manual Reference Counting) getauft.

ARC kann beim Anlegen/Erstellen eines neuen Projektes als Grundeinstellung für alle zu kompilierenden (*.m) Dateien aktiviert werden, oder jedoch deaktiviert, so dass wie bisher auch der MRC-Kompiler-Modus benutzt wird. Entsprechend dieser Einstellung entscheidet man sich für das Projekt ob man ARC-Code schreiben wird, oder jedoch MRC-Code. Da für bisherige iOS Projekte ausschließlich MRC-Code geschrieben wurde, hat Apple für den Umstieg bisheriger Projekte auf ARC einen Konvertierungs-Assistenten direkt in XCode integriert.

 

arc-Konverter-Assitent

Dieser Assistent versucht in 3 Schritten alle MRC-Dateien im Projekt in ARC-Dateien umzuwandeln. Dies erfolgt nicht ganz automatisch, so dass in Problemfällen (und die sind in real-life Projekten grundsätzlich immer da)  ein Eingreifen und Zutun des Entwicklers  (also Codeänderungen) für das erfolgreiche Abschließen der Konvertierung unvermeidbar ist. Ein Arbeitsschritt, der in einem kleinen Projekt mit 20 Klassen sicher in einigen Minuten erledigt ist. In einem großen Projekt jedoch, das über mehrere Jahre gewachsen ist, mehrere hunderte große Klassen enthält, mit komplizierten Beziehungen agiert, mit Abhängigkeiten zu weiteren externen Code-Bibliotheken arbeitet und viel non-Objective-C Code enthält sicher ein grundlegend zu überdenkender Task ist, für den man viel Zeit und Konzentration in Anspruch nehmen muss.

Glücklicherweise ist die Sache nicht ganz so schwarz oder weiß, als dass man sich grundsätzlich entweder für ARC oder MRC in seinen Projekten entscheiden müsste. Tatsächlich ist der Kompilier-Modus einer einzelnen Objective-C *.m-Implementierungsdatei jeweils frei wählbar. So kann beispielsweise ein im MRC-Modus konfiguriertes Projekt einzelne Code-Dateien enthalten, die nach der ARC-Metapher geschrieben wurden. Diese ARC-Dateien müssen dann mit dem Kompiler-Flag -fobjc-arc versehen werden, damit der korrekte Modus auch angewandt wird. Umgekehrt können ARC-Projekte auch einzelne Klassen mit MRC-Code enthalten – die MRC-Dateien wären hierbei entsprechend mit -fno-objc-arc dem Kompiler kenntlich zu machen. Eine Mischform von MRC/ARC Klassen in einem Projekt ist nicht nur möglich, sondern für viele Projekte gängige Praxis für die nächsten Monate der „Übergangszeit“.

Tipp: XCode hat die Eigenschaft dass beim Hinzufügen von bestehenden Code-Dateien (z.B. aus bestehenden Libraries) in ein Projekt diese sequentiell in die Kompilier-Liste eingefügt werden. (in der Reihenfolge wie hinzugefügt und nicht nach Name sortiert: <PROJECT>/<APPTARGET>/Build Phases/Compile Sources Section). Somit bietet es sich an frühzeitig nach dem Anlegen des Projektes den abweichenden Kompiliermodus der betroffenen neu hinzugefügten Dateien korrekt zu wählen. (z.B. werden in einem bisherigen MRC Projekt „neue“ ARC-Klassen hinzugefügt)

arc-multiselection

Durch die Möglichkeit der Multiselektion ist schnell ein größerer Satz von .m-Dateien markiert und bereit für das Setzen des entsprechenden Kompiler-Flags. Per „Enter“ öffnet sich nun das Eingabefenster für die Eingabe – im bebilderten Fall -fobjc-arc.

arc multiselection

Würde man jetzt „Done“ klicken, würde nicht wie erwartet das Flag für alle selektierte Dateien gesetzt werden, sondern lediglich für eine einzige. Hier hat XCode anscheinend derzeit noch einen Bug – durch erneutes Drücken von „Enter“ erfolgt jedoch die Übernahme für die komplette Multiselektion, wie gewünscht. (Update: ab XCode 4.3 wurde dieser erwähnte Multiselektion-Bug gefixt)

Vorsicht: Das Vergessen des Setztens des korrekten Kompilerflags bei solchen „Mischform“-Projekten kann zu ernsthaften Problemen führen. In einem ARC Projekt, in das beispielsweise MRC-Klassen hinzugefügt werden und das Flag-Setzen vergessen wurde nörgelt der Kompiler lautstark beim Kompilierversuch der betroffenen MRC Klassen, da sie verbotenerweise noch retain/release/autorelease Methodenaufrufe beinhalten. So weit, so gut – lässt sich nach der auffälligen Fehlermeldung korrigieren. In einem MRC-Projekt jedoch, in das ARC-Klassen hinzugefügt werden und dabei das korrekte Flagsetzen ausgelassen wurde, passiert nichts. –> Der Kompiliervorgang wird erfolgreich abgeschlossen, die App sogar erfolgreich gestartet. Was jedoch stillschweigend tatsächlich passiert, ist dass alle ARC-Klassen bei ihrer Code-Ausführung gnadenlos leaken (also allokierten Speicher nicht mehr freigeben, da sie bewusst keine release-Methodenaufrufe mehr beinhalten). Eine sehr gefährliche Sache. Durch einen Trick bekommt man es jedoch in seinen ARC-Klassen hin, dass ein Vergessen des korrekten Kompilerflags unmöglich gemacht wird, ähnlich wie es bereits im umgekehrten Fall ist, indem der Kompiliervorgang durch einen sprechenden Fehler auf den Misstand hinweist. Durch Hinzufügung des folgenden Makros in jede eigene ARC .m-Datei gehört das „leaken aus Nachlässigkeit“ der Vergangenheit an.

Bewerte diesen Beitrag
0 Kommentare

Dein Kommentar

An Diskussion beteiligen?
Hinterlasse uns Deinen Kommentar!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.