Ich habe ARC noch nicht verwendet, da der Großteil des Codes in dem Projekt, an dem ich gerade arbeite, vor iOS 5.0 geschrieben wurde.
Ich habe mich nur gefragt, ob die Bequemlichkeit, nicht manuell zu behalten / freizugeben (und vermutlich zuverlässigerer Code, der sich daraus ergibt?) Die Kosten für die Verwendung von ARC überwiegt. Welche Erfahrungen haben Sie mit ARC gemacht und würden Sie es empfehlen?
So:
- Wie viel Nutzen kann ARC für ein Projekt bringen?
- Hat ARC Kosten wie Garbage Collection in Java?
- Haben Sie ARC verwendet und wenn ja, wie haben Sie es bisher gefunden?
iphone
objective-c
ipad
ios5
automatic-ref-counting
Simon Withington
quelle
quelle
Antworten:
Es gibt keinen Nachteil. Benutze es. Mach es heute. Es ist schneller als Ihr alter Code. Es ist sicherer als Ihr alter Code. Es ist einfacher als Ihr alter Code. Es ist keine Speicherbereinigung. Es hat keinen GC-Laufzeitaufwand. Die Compiler-Einfügungen behalten und geben sie an allen Stellen frei, die Sie sowieso haben sollten. Aber es ist schlauer als Sie und kann diejenigen optimieren, die nicht wirklich benötigt werden (genau wie es Schleifen abrollen, temporäre Variablen, Inline-Funktionen usw. eliminieren kann).
OK, jetzt erzähle ich Ihnen von den kleinen Nachteilen:
Wenn Sie ein langjähriger ObjC-Entwickler sind, werden Sie ungefähr eine Woche lang zucken, wenn Sie ARC-Code sehen. Sie werden sehr schnell darüber hinwegkommen.
Es gibt einige (sehr) kleine Komplikationen bei der Überbrückung zum Core Foundation-Code. Es gibt etwas mehr Komplikationen im Umgang mit allem, was ein
id
als behandeltvoid*
. Dinge wie C-Arrays vonid
können etwas mehr Nachdenken erfordern, um richtig zu machen. Ein ausgefallener Umgang mit ObjCva_args
kann ebenfalls Probleme verursachen. Die meisten Dinge, die Mathematik auf einem ObjC-Zeiger betreffen, sind schwieriger. Sie sollten auf keinen Fall viel davon haben.Sie können kein
id
in ein setzenstruct
. Dies ist ziemlich selten, wird aber manchmal zum Packen von Daten verwendet.Wenn Sie die korrekte KVC-Benennung nicht befolgt und ARC- und Nicht-ARC-Code gemischt haben, treten Speicherprobleme auf. ARC verwendet die KVC-Benennung, um Entscheidungen über die Speicherverwaltung zu treffen. Wenn es nur ARC-Code ist, spielt es keine Rolle, da es auf beiden Seiten das gleiche "Falsche" macht. Wenn es sich jedoch um gemischtes ARC / Nicht-ARC handelt, liegt eine Nichtübereinstimmung vor.
ARC verliert während der Auslösung von ObjC-Ausnahmen Speicher. Eine ObjC-Ausnahme sollte sehr nahe an der Beendigung Ihres Programms liegen. Wenn Sie eine erhebliche Anzahl von ObjC-Ausnahmen abfangen, verwenden Sie diese falsch. Dies kann mit behoben werden
-fobjc-arc-exceptions
, führt jedoch zu den unten beschriebenen Strafen:ARC verliert während der Auslösung von ObjC- oder C ++ - Ausnahmen im ObjC ++ - Code keinen Speicher, dies geht jedoch zu Lasten der Zeit- und Raumleistung. Dies ist ein weiterer Grund in einer langen Liste von Gründen, die Verwendung von ObjC ++ zu minimieren.
ARC funktioniert unter iPhoneOS 3 oder Mac OS X 10.5 oder früher überhaupt nicht. (Dies hindert mich daran, ARC in vielen Projekten zu verwenden.)
__weak
Zeiger funktionieren unter iOS 4 oder Mac OS X 10.6 nicht richtig, was schade ist, aber ziemlich einfach zu umgehen ist.__weak
Zeiger sind großartig, aber sie sind nicht das Hauptverkaufsargument von ARC.Für mehr als 95% des Codes ist ARC brillant und es gibt überhaupt keinen Grund, dies zu vermeiden (vorausgesetzt, Sie können mit den Einschränkungen der Betriebssystemversion umgehen). Für Nicht-ARC-Code können Sie übergeben
-fno-objc-arc
Datei für Datei weitergeben. Xcode macht dies leider viel schwieriger als es in der Praxis sein sollte. Sie sollten wahrscheinlich Nicht-ARC-Code in ein separates xcodeproj verschieben, um dies zu vereinfachen.Wechseln Sie abschließend so schnell wie möglich zu ARC und schauen Sie niemals zurück.
BEARBEITEN
Ich habe einige Kommentare im Sinne von "Die Verwendung von ARC ist kein Ersatz für die Kenntnis der Cocoa-Speicherverwaltungsregeln" gesehen. Dies ist meistens wahr, aber es ist wichtig zu verstehen, warum und warum nicht. Erstens, wenn Ihr gesamter Code ARC verwendet und Sie die drei magischen Wörter verletzen überall gegen den , haben Sie immer noch keine Probleme. Schockierend zu sagen, aber los geht's. ARC behält möglicherweise einige Dinge bei, die Sie nicht beibehalten möchten, aber es gibt sie auch frei, sodass es keine Rolle spielt. Wenn ich heute eine neue Klasse in Cocoa unterrichten würde, würde ich wahrscheinlich nicht mehr als fünf Minuten mit den eigentlichen Speicherverwaltungsregeln verbringen, und ich würde wahrscheinlich nur die Speicherverwaltungs-Namensregeln erwähnen, während ich über die KVC-Benennung diskutiere. Mit ARC,
Aber Sie könnten kein anständiger fortgeschrittener Programmierer werden. Sie müssen die Regeln kennen, um eine korrekte Verbindung mit Core Foundation herzustellen, und jeder fortgeschrittene Programmierer muss sich irgendwann mit CF befassen. Und Sie müssen die Regeln für gemischten ARC / MRC-Code kennen. Und Sie müssen die Regeln kennen, wenn Sie anfangen, mit
void*
Zeigern herumzuspielenid
(die Sie weiterhin benötigen, um KVO korrekt auszuführen). Und Blöcke ... nun, Blockspeicherverwaltung ist einfach komisch.Mein Punkt ist also, dass die zugrunde liegende Speicherverwaltung immer noch wichtig ist, aber wo ich früher viel Zeit damit verbracht habe, die Regeln für neue Programmierer festzulegen und neu zu formulieren, wird ARC mit ARC zu einem fortgeschritteneren Thema. Ich möchte lieber neue Entwickler dazu bringen, in Objektgraphen zu denken, als ihre Köpfe mit den zugrunde liegenden Aufrufen zu füllen
objc_retain()
.quelle
Bessere, technischere Antworten als meine werden kommen, aber hier ist:
quelle
Der Vorteil ist ein erheblicher Schutz vor häufigen Fehlern bei der Speicherverwaltung. Leckagen, die dadurch verursacht werden, dass ein Objekt nicht freigegeben wird, und Abstürze, die darauf zurückzuführen sind, dass ein Objekt nicht beibehalten oder vorzeitig freigegeben wird, sollten erheblich verringert werden. Sie müssen das Referenzzählerspeichermodell noch verstehen, damit Sie Ihre Referenzen als stark oder schwach klassifizieren, Aufbewahrungszyklen vermeiden usw. können.
In iOS gibt es keine Speicherbereinigung. ARC ähnelt GC darin, dass Sie Objekte nicht manuell beibehalten oder freigeben müssen. Es ist anders als bei GC, dass es keinen Müllsammler gibt. Das Retain / Release-Modell gilt weiterhin. Der Compiler fügt lediglich die entsprechenden Speicherverwaltungsaufrufe zur Kompilierungszeit für Sie in Ihren Code ein.
Es ist ein wenig beunruhigend, wenn Sie es gewohnt sind, auf das Zählen zu verweisen, aber das ist nur eine Frage der Gewöhnung und des Vertrauens, dass der Compiler wirklich das Richtige tut. Es scheint eine Fortsetzung der Änderung der Eigenschaften zu sein, die mit Objective-C 2.0 einherging. Dies war ein weiterer großer Schritt zur Vereinfachung der Speicherverwaltung. Ohne die manuellen Speicherverwaltungsaufrufe wird Ihr Code etwas kürzer und leichter zu lesen.
Das einzige Problem mit ARC ist, dass es in älteren Versionen von iOS nicht unterstützt wird. Sie müssen dies berücksichtigen, bevor Sie sich für die Einführung entscheiden.
quelle
Ich denke, ARC ist eine großartige Idee. Im Vergleich zu GC können Sie Ihren Kuchen auch essen. Ich neige dazu zu glauben, dass MRC eine unschätzbare "Disziplin" für das Speichermanagement auferlegt, von der jeder profitieren würde. Ich stimme aber auch zu, dass das eigentliche Problem, dessen Sie sich bewusst sein müssen, Objektbesitz und Objektdiagramme sind (wie viele betont haben) und nicht die Referenzanzahl auf niedriger Ebene an sich.
Fazit: ARC ist KEINE Freikarte, um sich Gedanken über das Gedächtnis zu machen. Es ist ein Werkzeug, das Menschen dabei hilft, sich wiederholende Aufgaben zu vermeiden, die Stress verursachen und fehleranfällig sind und daher besser an eine Maschine (in diesem Fall den Compiler) delegiert werden.
Trotzdem bin ich persönlich eine Art Handwerker und habe den Übergang noch nicht geschafft. Ich habe gerade angefangen, Git zu benutzen ...
AKTUALISIEREN: Also habe ich mein gesamtes Spiel migriert, einschließlich der gl-Bibliothek, und bisher keine Probleme (außer mit dem Migrationsassistenten in Xcode 4.2). Wenn Sie ein neues Projekt starten, machen Sie es.
quelle
Ich habe es in einigen (zugegebenermaßen kleinen) Projekten verwendet und habe nur gute Erfahrungen gemacht, sowohl was die Leistung als auch die Zuverlässigkeit betrifft.
Ein kleiner Hinweis zur Vorsicht ist, dass Sie die Do: s und Don't: s von schwachen Referenzen lernen müssen, um keine Referenzschleifen zu verursachen, wenn Sie Ihre Benutzeroberfläche selbst codieren. Der Designer leistet in der Regel gute Arbeit automatisch, wenn Sie Ihre GUI damit einrichten.
quelle
Der einzige Nachteil, auf den ich gestoßen bin, ist, wenn Sie eine Bibliothek mit vielen CoreFoundation-Funktionen und -Daten verwenden. In MRC mussten Sie sich keine Gedanken über die Verwendung von a
CFStringRef
anstelle von machenNSString*
. In ARC müssen Sie angeben, wie die beiden interagieren (Basisbrücke? Geben Sie das CoreFoundation-Objekt frei und verschieben Sie es in ARC? Erstellen Sie ein Cocoa-Objekt als +1 CoreFoundation-Objekt?). Unter OS X ist es nur unter 64 verfügbar. Bitcode (obwohl ich einen Header habe, der das umgeht…).quelle