6.6 Was Sie schon immer über Instruments wissen wollten, aber nie zu fragen wagten
Und nun zu etwas ganz anderem: Wie gut kennen Sie eigentlich noch die Speicherverwaltungsregeln? In welchen Fällen hält noch mal eine Variable das Objekt, auf das sie verweist? Und wie war das noch mal bei Core Foundation? Wenn Sie sich jetzt unsicher sind, dürfen Sie natürlich gerne zurückblättern. Allerdings wird Ihnen auch dann, wenn Sie die Regeln und ihre Anwendung beherrschen, wahrscheinlich von Zeit zu Zeit der eine oder andere Speicherverwaltungsfehler unterlaufen. Wenn Sie Glück haben, sendet Ihnen Ihr Programm zarte Hinweise. Im schlechtesten Fall macht es das indes nur bei den Nutzern Ihrer App. Nach Murphys Gesetz – »Was schiefgehen kann, geht schief« – ist Letzteres der Regelfall.
Sie können und sollten den Analyzer über Ihren Programmcode laufen lassen und versuchen, möglichst alle Warnungen zu beseitigen. Leider findet auch der Analyzer nicht alle Fehler, und auch mit dem Debugger mogelt sich schon mal die eine oder andere Schwachstelle durch. Doch es gibt ein Gegenmittel: Instruments und Arbeit. Da Sie von Arbeit sicherlich schon mal gehört haben, dreht sich dieser Abschnitt hauptsächlich um Instruments.
Instruments ist ein Programm aus den Entwicklungswerkzeugen von Apple, das Sie bereits zusammen mit dem SDK installiert haben. Es erlaubt die Aufzeichnung und anschließende Analyse unterschiedlicher Messwerte Ihrer Programme, um deren Schwachstellen zu finden. Es kann Ihnen jedoch nur Hinweise geben, wo Sie nach den Schwachstellen suchen müssen. Es macht Ihnen leider keine Vorschläge zu deren Behebung.
Instruments funktioniert dabei nach einem Baukastensystem, bei dem jeder Baustein ein Messinstrument ist. Sie können für Ihre Instruments-Sitzungen diese Bausteine beliebig kombinieren. Zurzeit bietet Instruments ungefähr fünfzig solcher Messinstrumente an, von denen allerdings einige für OS X vorbehalten sind.
Sie starten Instruments, indem Sie den Button Run oben links in Xcode gedrückt halten und im Dropdown-Menü den Punkt Profile auswählen (siehe Abbildung 6.38).
Abbildung 6.38 Starten von Instruments
Nach dem Start öffnet Instruments den in Abbildung 6.39 dargestellten Auswahldialog, mit dem Sie ein bestehendes Instruments-Dokument oder eine Dokumentvorlage auswählen können. In der Regel benutzen Sie die zweite Option. Hier bietet Ihnen Instruments bereits eine Palette mit vorkonfigurierten Mess-Szenarien an. Alternativ können Sie auch eine leere Vorlage auswählen, die Sie individuell nach Ihren Bedürfnissen konfigurieren können. Für den Anfang sollten Sie lieber ein vorkonfiguriertes Szenario verwenden. Falls Instruments Ihr Programm sofort startet, ohne vorher den Auswahldialog anzuzeigen, haben Sie wahrscheinlich das Programm noch in Instruments geöffnet. Schließen Sie also am besten immer alle Fenster von Instruments, bevor Sie eine neue Analyse starten.
Abbildung 6.39 Auswahldialog in Instruments
Operation am lebenden Programm
Damit Sie einen anschaulichen Eindruck von Instruments bekommen, finden Sie auf der beiliegenden DVD und im GIT-Repository zum Buch das Beispielprojekt Instruments. Es stellt verschiedene Analysesituationen bereit und enthält deshalb absichtlich Schwachstellen für die nachfolgend beschriebenen Mess-Szenarien. Alle nachfolgenden Beispiele beziehen sich auf diese App, auch wenn nicht extra darauf hingewiesen wird.
Die Schwachstellen im Beispielprojekt sind relativ offensichtlich. Wahrscheinlich verstecken sie sich in Ihren Programmen wesentlich besser. Hier kommt dann das zweite Gegenmittel ins Spiel: Arbeit.
6.6.1 Spiel mir das Lied vom Leak

Eine der wichtigsten Aufgaben von Instruments ist das Auffinden von Speicherlecks. Speicherlecks führen im schlimmsten Fall nicht direkt zu einem Fehlverhalten Ihres Programms. Stattdessen erhält es vom Betriebssystem Speicherwarnungen, deren Verarbeitung die App verlangsamen. Schließlich stürzt das Programm dann doch ab, wobei sich die Absturzsituation nur sehr schwer reproduzieren lässt.
Abbildung 6.40 Speicheranalyse mit Instruments
Öffnen Sie das Instruments-Projekt in Xcode, und starten Sie Instruments wie oben beschrieben. Im Auswahldialog (siehe Abbildung 6.39) wählen Sie die Schablone Leaks aus, mit der Sie Speicherlecks finden können. Instruments startet Ihre App, abhängig von Ihrer Auswahl in Xcode, im Simulator oder auf einem iOS-Gerät. Außerdem öffnet es das in Abbildung 6.40 dargestellte Fenster. Die Schablone erzeugt zwei Messinstrumente, die Sie in der linken Spalte oben finden. Mit Allocations messen Sie den Speicherverbrauch Ihrer App, während Leaks die Speicherlecks aufzeichnet. Wenn Sie im oberen Bereich des Fensters ein Messinstrument auswählen, zeigt Instruments Ihnen im unteren Bereich dazu Detailinformationen an.
Automatisches Referenzenzählen und Speicherlecks
Durch die Einführung von ARC sollte die Suche nach Speicherlecks in den meisten Fällen obsolet sein.
Allerdings kann auch Code, der sich formal korrekt an die Speicherverwaltungsregeln hält oder ARC einsetzt, Speicherlecks enthalten. Wenn Ihr Programm die nicht mehr benötigten Objekte sammelt, anstatt sie freizugeben, kann es auch hier passieren, dass der Hauptspeicher vollläuft.
Ein Beispiel dafür sind Retain-Zyklen, bei denen sich Objekte gegenseitig im Hauptspeicher halten. Im einfachsten Fall sind das zwei Objekte, die jeweils über eine Property mit dem Speicherverwaltungstyp retain oder strong aufeinander verweisen. Wenn der Programmcode diesen Zyklus nicht explizit unterbricht, bleiben diese Objekte bis zum Programmende im Hauptspeicher.
Eine weitere potenzielle Quelle für Speicherlecks ist die Verwendung der C-Frameworks wie Core Foundation oder Core Image, da es hierfür ja kein automatisches Referenzenzählen gibt. Das gilt natürlich auch für fremde C- oder C++-Bibliotheken.
Zum Glück gibt es jedoch mit Leaks und Alloctions zwei Messinstrumente, die Ihnen auch hier bei der Suche nach Speicherlecks helfen.
Nach dem Start erscheinen neben Allocations ein paar blaue senkrechte Striche, während der Bereich neben Leaks leer bleibt. Da das Programm bislang noch kein Speicherleck erzeugt hat, ist das auch richtig so. Wenn Sie den Knopf Make Leak in der iPhone-App Instruments drücken, erscheinen im Leaks-Bereich ein roter und mehrere blaue Balken (siehe Abbildung 6.41). Die roten Balken kennzeichnen das Auftreten von Speicherlecks, während die blauen Balken das Verhältnis der Leckgrößen im Verlauf der Zeit darstellen. Dabei ist nicht die absolute Höhe der Balken interessant, sondern die Höhe und Verteilung der Stufen. Je höher eine Stufe ist, umso größer ist das dazugehörende Leck. Je dichter die Stufen beieinanderstehen, umso mehr Speicherlecks weist ein Programmbereich auf. Sie können durch das erneute Drücken des Buttons weitere Speicherlecks erzeugen und so die Stufenbildung beobachten.
Abbildung 6.41 Grafische Anzeige eines Speicherlecks in Instruments
Oben links im Fenster befindet sich der Button Stop. Damit können Sie die Ausführung der App beenden, wenn Sie genug Leaks gesammelt haben. Durch Auswählen des Leaks-Instruments in der Spalte Instruments wie in Abbildung 6.41 zeigt das Programm im unteren Fensterbereich Details dazu an. In der linken Spalte können Sie die Einstellungen des Instruments anpassen, während der Bereich auf der rechten Seite die gefundenen Speicherlecks auflistet (siehe Abbildung 6.42).
Einstellungssache
Leaks sammelt die Speicherlecks in regelmäßigen Intervallen. Die Intervall-Länge ist standardmäßig auf zehn Sekunden eingestellt. Über das Eingabefeld Snapshot interval können Sie diesen Wert anpassen. Sie müssen also immer erst bis zum Ende der Intervalle warten, bis Leaks Ihnen die Speicherlecks anzeigt.
Sie können diese Wartezeit allerdings auch durch Drücken des Buttons Snapshot Now abkürzen. Dann sammelt Leaks augenblicklich alle Speicherlecks. Wenn der Inhalt der Speicherlecks Sie interessiert, sollten Sie außerdem das Häkchen für Gather Leaked Memory Contents setzen.
Abbildung 6.42 Details des Leaks-Instruments
Wenn Sie den Pfeil eines Speicherlecks in der Spalte Address (siehe den Mauszeiger in Abbildung 6.42) anklicken, gelangen Sie zu den Details des Lecks. Hier können Sie unter anderem
den Referenzenzähler und die Erzeugungszeit relativ zum Programmstart sehen. Durch einen Doppelklick auf
die Zeile öffnet Instruments eine Quellcodeanzeige mit der Zeile, die das leckende
Objekt erzeugt hat. Außerdem können Sie sich über
+
beziehungsweise den Menüpunkt View • Extended Detail den Aufrufstapel anzeigen lassen (siehe Abbildung 6.43). Sie bekommen darüber in vielen Fällen einen recht guten Hinweis, wo Sie mit der
Fehlersuche für die Speicherverwaltung beginnen sollten.
Abbildung 6.43 Anzeige eines einfachen Lecks mit Aufrufstapel
Durch einen Doppelklick auf eine Zeile im Aufrufstapel können Sie sich die entsprechende Stelle im Quellcode anzeigen lassen. Das funktioniert natürlich nur für Symbole, deren Quellcode zum Projekt gehört. In der Regel sind das die Zeilen mit dem schwarzen User-Symbol.
Wenn Sie einen Doppelklick auf Zeile im Stapel ausführen, die in Abbildung 6.43 hervorgehoben ist, zeigt Instruments Ihnen die folgende Zeile an:
id theLeak = [[InstrumentsDemoObject alloc] init];
Sie befindet sich in der Methode makeLeak. Nach den Speicherverwaltungsregeln muss die Methode diesem Objekt entweder ein release oder ein autorelease senden, da die Variable theLeak das Objekt hält. Dieser Speicherverwaltungsfehler ist also ziemlich offensichtlich. Leider ist das jedoch in der Praxis in vielen Fällen nicht so einfach.
Zurück auf Los
Sie können von der Detailansicht zu den allgemeineren Ansichten zurückkehren, indem Sie auf die Pfeilsymbole oberhalb der Detailansicht (siehe die oberste Zeile in Abbildung 6.42) klicken.
Außerdem können Sie in jeder Ansicht die Spaltenanzeige durch einen Rechtsklick auf die Titelleiste an Ihre Bedürfnisse anpassen. Dadurch können Sie einzelne Spalten ausblenden. Die Reihenfolge der Spalten lässt sich durch Verschieben der Spaltenköpfe verändern und die Zeilensortierung durch einfaches Anklicken der Spaltenköpfe.
Über den Button Make Attribute Leak erzeugen Sie komplexere Speicherlecks. Damit Instruments ein Speicherleck erkennt, müssen Sie diesen Button allerdings mindestens zweimal anklicken. Wenn Sie sich danach die Details dieses Lecks ansehen, zeigt Instruments Ihnen vier Zeilen statt einer Zeile an (siehe Abbildung 6.44). Dabei enthält jede Zeile eine Speicherverwaltungsoperation, die das Programm auf dem leckenden Objekt ausgeführt hat. Die jeweilige Operation können Sie der Spalte Event Type entnehmen. Da das alle Speicherverwaltungsoperationen auf dem Objekt sind, wurden bei mindestens einer davon die Speicherverwaltungsregeln missachtet.
Abbildung 6.44 Detailanzeige für ein komplexeres Leck
In der Spalte Responsible Caller sehen Sie die Methode, die die Operation aufruft. In der vierten Zeile steht dort beispielsweise _UIApplicationHandleEvent oder bei älteren Instrumentsversionen etwas verständlicher[NSAutoreleasePool release]. Dieses Release hat also der Autorelease-Pool ausgelöst.
Instruments und die Systembibliotheken
Zu dieser Zeile kann Instruments Ihnen keinen Quellcode anzeigen, da es keinen Zugang dazu hat. Der Quellcode für den Autorelease-Pool befindet sich schließlich bei Apple und ist nicht öffentlich. Für die Überprüfung Ihrer Speicherverwaltung ist das auch nicht notwendig. Außerdem sollten Sie die Möglichkeit, dass Cocoa Touch ein Speicherleck erzeugt, erst nach Ausschluss aller anderen Möglichkeiten in Betracht ziehen. [ [Es gibt durchaus einige bekannte Speicherlecks in Cocoa Touch; die Wahrscheinlichkeit, dass Ihr Code den Fehler verursacht, ist jedoch wesentlich höher.]
Die ersten beiden angezeigten Zeilen verweisen auf den Convenience-Konstruktor object der Klasse InstrumentsDemoObject. Diese Methode enthält nur eine alloc-init-Autorelease-Aufrufkette und hält sich offensichtlich an die Speicherverwaltungsregeln. Es bleibt also nur noch die Methode makeAttributeLeak in der Klasse InstrumentsViewController als mögliche Ursache übrig (siehe Listing 6.97). Auch diese Methode scheint sich an die Speicherverwaltungsregeln zu halten, und beim ersten Aufruf erzeugt sie ja auch noch kein Leck.
- (IBAction)makeAttributeLeak {
attributeLeak = [[InstrumentsDemoObject object] retain];
}
Listing 6.97 Speicherleck bei Attributzuweisung
Wenn Sie die Methode indes wiederholt ausführen, gibt sie das Objekt, auf das attributeLeak verweist, nicht frei. Nach den Speicherverwaltungsregeln muss sie das allerdings machen, da die Variable das Objekt ja hält. Um diesen Speicherverwaltungsfehler zu beheben, sollten Sie lieber den Setter verwenden.
- (IBAction)makeAttributeLeak {
self.attributeLeak = [InstrumentsDemoObject object];
}
Listing 6.98 Methode ohne Speicherleck
Speicherverwaltung
Der Speicherverwaltungsfehler in der Methode makeAttributeLeak ist für Anfänger schwer zu erkennen, und auch der Analyzer in Xcode 4 findet ihn nicht. Sie können solche Fehler jedoch durch die konsequente Verwendung von Accessoren vermeiden.
6.6.2 Ich folgte einem Zombie

Was passiert eigentlich, wenn Sie ein Objekt hinter einem Dangling Pointer weiterverwenden? Die Antwort ist nichts für schwache Nerven, lieber Leser, denn es entsteht ein Zombie, der in Ihrem Speicher Angst und Schrecken verbreitet. Das Schlimme an Zombies ist, dass das von ihnen angerichtete Unheil erst lange nach seiner Entstehung auftreten kann.
In Ihrer App entsteht ein Zombie, wenn Sie einen Verweis auf ein Objekt verwenden, nachdem Sie es freigegeben haben. Die Freigabe muss dabei indes nicht unbedingt über die gleiche Variable wie der Zombie-Zugriff erfolgen. Das erschwert natürlich die Suche nach diesen Bestien.
Abbildung 6.45 Ein Zombie im Hauptspeicher
Abbildung 6.45 veranschaulicht einen Zombie im Hauptspeicher. Alles beginnt mit einem Objekt, das seine Daten irgendwo im Hauptspeicher schön ordentlich abgelegt hat A. Irgendwann gibt das Programm den Speicherbereich dieses Objekts frei, obwohl es noch Referenzen auf dieses Objekt hat. Dadurch hat es einen Zombie erzeugt, und alle Verweise darauf sind Dangling Pointer B. Der Zugriff auf dieses Objekt über die Dangling Pointer muss indes jetzt noch nicht zu einem Fehler oder Absturz führen, da der Speicherbereich ja in der Regel immer noch die Daten des ursprünglichen Objekts enthält, was die Abbildung durch graue Ziffern darstellt.
Jedes Mal, wenn das Programm danach ein neues Objekt anlegt, besteht jedoch die Möglichkeit, dass dieses neue Objekt den Speicherbereich des Zombies oder Teile davon belegt und überschreibt C. Diese Situation kann unterschiedliche Fehler hervorrufen. Das Programm kann sich unvorhergesehen verhalten oder abstürzen. In der Regel bemerken Sie erst in dieser Situation, dass Ihr Programm einen Zombie enthält.
Die Beispiel-App Instruments erlaubt Ihnen auch die Erzeugung von Zombies. Sie brauchen dabei keine Angst zu haben. Sie machen das ja unter Laborbedingungen, und da kann Ihnen nichts passieren – na ja, fast nichts. Starten Sie die App über den Profile-Button aus Xcode in Instruments, und wählen Sie die Schablone Zombies im Auswahldialog aus.
Abbildung 6.46 Instruments hat einen Zombie entdeckt.
Nach dem Start zeigt Instruments Ihnen den Speicherverbrauch der App an. Wenn Sie zweimal auf den Button Make Zombie klicken, hält die Ausführung an. Instruments zeigt einen Dialog wie in Abbildung 6.46. Wenn Sie den Pfeil neben der Speicheradresse anklicken, gelangen Sie zu einer Auflistung der Speicherverwaltungsoperationen, die das Programm auf dem Objekt ausgeführt hat.
Abbildung 6.47 Speicherverwaltungsoperationen eines Zombies
Die letzte Zeile enthält die Methode oder Funktion, die auf den Zombie zugegriffen hat. Es ist die Systemfunktion _NSDescriptionWithLocaleFunc, auf deren Quellcode Sie keinen Zugriff haben. Diese Funktion hat zwar auf den Zombie zugegriffen, sie hat ihn jedoch nicht erzeugt. Der Zombie ist durch das Release in der fünften Zeile entstanden, wie Sie an dem Referenzenzähler sehen können. Da dieses Release jedoch vom Autorelease-Pool gesendet wurde, kann diese Zeile nicht direkt für den Fehler verantwortlich sein. Der Verursacher ist entweder das Autorelease der zweiten oder das Release der vierten Zeile.
Auch hier können Sie sich über den Aufruf von View • Extended Detail beziehungsweise
+
jeweils den Aufrufstapel zu den Anweisungen auf der rechten Seite des Fensters anzeigen
lassen. Der Stapel stellt alle Systemsymbole in grauer Schrift mit einem farbigen
Icon dar. Dagegen stellt er die Symbole aus Ihrem Programmcode in schwarzer Schrift
mit einem schwarzen Icon dar. Abbildung 6.48 zeigt einen Ausschnitt eines Aufrufstapels. Sie können durch einen Doppelklick auf
diese Symbole in die entsprechende Stelle des Quelltextes springen.
Abbildung 6.48 Detailansicht und Ausschnitt des Aufrufstapels
Da sich der Convenience-Konstruktor object an die Speicherverwaltungsregeln hält, bleibt überraschenderweise nur die Methode makeZombie als Kandidat übrig.
- (IBAction)makeZombie {
id theZombie = [InstrumentsDemoObject object];
NSLog(@"zombies=%@", self.zombies);
[self.zombies addObject:theZombie];
[theZombie release];
}
Da die Methode object nicht auf die erste Speicherverwaltungsregel passt, hält die Variable theZombie nicht das Objekt. Also darf sie das Objekt auch nicht freigeben. Der Fehler liegt also in der letzten Zeile der Methode, die ein Release an die Variable theZombie sendet.
Automatisches Referenzenzählen und Zombies
Von einem ARC-Compiler übersetzter Code sollte in der Regel keine Zombies mehr erzeugen, wenn Sie anstatt assign den Speicherverwaltungstyp weak in den Property-Deklarationen verwenden. Sie können zwar auch mit eingeschaltetem ARC Zombies erzeugen, indem Sie beispielsweise Void-Zeiger oder den Modifizierer __unsafe_unretained verwenden. Diese Fälle sollten in der Praxis allerdings extrem selten auftreten.
6.6.3 Time Bandits
Instruments hilft Ihnen allerdings nicht nur beim Finden Ihrer Speicherverwaltungsfehler, sondern es kann auch andere Schwachstellen des Programms aufdecken. Zu den gesuchtesten Schwachstellen in Programmen gehören die Methoden und Funktionen, die Ihr Programm langsam und schwerfällig machen. Mit dem Messinstrument Time Profiler können Sie wunderbar den Zeitverbrauch Ihrer Methoden und Funktionen messen.
Je öfter Sie im Instruments-Beispielprogramm auf den Button Compute Sum drücken, umso länger braucht die App für die Berechnung der angezeigten Werte. Anscheinend ist die Implementierung also für größere Werte unzureichend. Um dem Zeitfresser auf die Spur zu kommen, starten Sie das Programm in Instruments aus Xcode heraus. Im Auswahldialog wählen Sie die Schablone Time Profiler aus.
Nach dem Start der App bleibt der untere Bereich zunächst leer. Wenn Sie einige Male den Button Compute Sum drücken, füllt Instruments die Anzeige mit Funktions- und Methodennamen. Stellen Sie die Sortierung nach der ersten Spalte, Running (Self), absteigend ein. Sie zeigt Ihnen den absoluten und den relativen Zeitverbrauch für die Ausführung des jeweiligen Symbols. Nach mehrfachem Drücken des Buttons erscheint das Symbol objc_msgSend als oberstes Element in der Anzeige. Diese C-Funktion gehört zur Objective-C-Runtime und ist für das Versenden von Nachrichten verantwortlich. Das Programm verwendet also anscheinend einen großen Teil seiner Rechenzeit für das Versenden von Nachrichten.
Hinter jedem Symbol verbirgt sich ein Aufrufstapel, den Sie sich durch Anklicken des
Dreiecks links neben dem Symbol ansehen können. Wenn Sie dabei die
-Taste gedrückt halten, klappen Sie den kompletten Baum auf einmal auf. Wenn Sie auf
diese Weise das Dreieck neben dem Symbol objc_msgSend anklicken, sollte die Anzeige ungefähr so wie in Abbildung 6.49 aussehen.
Abbildung 6.49 Aufgeklappter Aufrufstapel
Das zweite Symbol in dem Stapel ist die Methode computeSum in der Klasse InstrumentsDemoObject. Anscheinend hat diese Methode einen gesegneten Hunger auf die wertvolle Rechenzeit.
Häufig interessieren Sie sich bei der Laufzeitanalyse nicht für die Systemmethoden und -funktionen. Wenn Sie auf der linken Seite unter der Rubrik Call Tree die Optionen Show Obj-C Only und Hide System Libraries einschalten, schrumpft die Anzeige auf der rechten Seite zusammen. Sie sehen dann nur noch die von Ihnen erstellten Methoden. Wenn Sie außerdem die Option Top Functions einschalten, finden Sie in der Anzeige auch die Methode sum (Abbildung 6.50). Durch einen Doppelklick auf die Zeile gelangen Sie zur Quellcodeansicht.
Abbildung 6.50 Gefilterter Aufrufstapel
Dort sehen Sie jedoch nicht nur den Quelltext, sondern auch Prozentzahlen an einigen Zeilen. Falls dort keine Prozentzahlen stehen, können Sie die Ansicht über das Zahnradsymbol rechts über dem Quelltext anpassen. Wählen Sie dort den Punkt View as Value aus. Diese Prozentzahl gibt jeweils die relative Zeit für die Ausführung der Zeile an.
Anscheinend verbraucht die Methode sum ihre Rechenzeit fast komplett im Schleifenrumpf für den Aufruf der Methode successorWithIndex: (siehe Abbildung 6.51). Instruments hebt diese Zeile freundlicherweise auch noch rot hervor und unterstreicht den Methodennamen.
Abbildung 6.51 Anzeige des Zeitverbrauchs im Quelltext
Wenn Sie den Methodennamen anklicken, gelangen Sie zum Quelltext dieser Methode. Auch hier zeigt Instruments Ihnen wieder den relativen Zeitverbrauch der Zeilen in Prozent an. Diese Methode verbraucht den größten Teil ihrer Rechenzeit für den Aufruf der Property successor. Dabei hängen die genauen Zahlen allerdings davon ab, wie oft Sie den Button gedrückt haben.
Abbildung 6.52 Zeitverbrauch in der Methode »successorWithIndex:«
Da es sich um eine synthetisierte Property handelt, sieht das zunächst nach einer Sackgasse aus. Ein einzelner lesender Property-Aufruf verbraucht natürlich nicht so viel Zeit. Allerdings befindet er sich in einer Schleife, und die Methode successorWithIndex: befindet sich ebenfalls in einer Schleife. Die Anzahl der Schritte der inneren Schleife hängt von dem Parameter inIndex ab. Dessen Wert ist der Schleifenindex der äußeren Schleife. Wenn die äußere Schleife bis 8 läuft, dann ruft die App successorWithIndex: insgesamt 8-mal auf und liest die Property 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28-mal aus. Bei einer Länge von 1000 kommen schon 500.500 Zugriffe zustande, und bei 8000 sind es schon über 32 Millionen. Das verbraucht natürlich auch einiges an Rechenzeit.
Zur Behebung dieses Performance-Leaks ist also eine Neuimplementierung von sum notwendig. Anstatt auf die verkettete Liste über einen Index zuzugreifen, sollte sich die Schleife lieber über einen Zeiger durch die Liste hangeln:
- (NSUInteger)sum {
NSUInteger theSum = 0;
InstrumentsDemoObject *theItem = self;
while(theItem) {
theSum += theItem.counter;
theItem = theItem.successor;
}
return theItem;
}
Listing 6.100 Effizientere Implementierung der Summenberechnung
Dieses Verfahren besucht jedes Listenelement nur einmal. Bei einer Listenlänge von 8000 Einträgen liest diese Implementierung den Nachfolger auch nur 8000-mal aus.
Das leidige Thema Arbeit
Instruments kann Ihnen nur Hinweise auf die Schwachstellen in Ihren Programmen liefern. Die Behebung überlässt es großzügigerweise Ihnen ganz allein. Für die Suche nach Speicherverwaltungsfehlern kommen Sie also trotz Instruments nicht um die Kenntnis der Regeln herum.
Die Zeiträuber in Ihrer App zu suchen und zu beseitigen ist da schon komplizierter. Zwar liefert der Time Profiler Ihnen hier gute Hinweise; doch die Probleme zu beseitigen ist unter Umständen sehr schwierig oder gar unmöglich. Es muss ja schließlich nicht immer ein effizienteres Verfahren für die entsprechende Aufgabe geben.
Ihr Kommentar
Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.



















Jetzt bestellen





