Wie wir wissen, benötigen wir mit ARC ein __bridge
, um eine ID in ein void *
zu konvertieren:
So sind C-Funktionsaufrufe:
%Vor% Ich denke, das sollte auch für die Methoden gelten, und zwar für diesen ARC in iOS 5-Lernprogramm starten gibt das folgende Beispiel an und sagt, dass __bridge
benötigt wird:
Heute jedoch habe ich versehentlich einen __bridge
bei einem Methodenaufruf in einem meiner Programme gelöscht, und der Code wurde kompiliert und ohne Probleme ausgeführt. Die __bridge
im obigen Beispiel scheint unnötig zu sein:
Stimmt das? Ist die __bridge
in diesem Fall wirklich unnötig? Oder das Entfernen ändert sich, was der Code bedeutet?
Dies wird in ARC-Dokumenten behandelt Abschnitt 3.3.3 (Hervorhebung von mir):
3.3.3 Konvertierung von beibehaltenen Objektzeigertypen in bestimmten Kontexten
[Anfang Apple 4.0, LLVM 3.1]
Wenn ein Ausdruck des beibehaltenen Objekt-Zeigertyps explizit umgewandelt wird zu einem C-haltbaren Zeigertyp ist das Programm wie besprochen schlecht ausgebildet oben, wenn das Ergebnis nicht sofort verwendet wird:
- zum Initialisieren eines Parameters in einer Objective-C-Nachricht senden, wobei der Der Parameter ist nicht mit dem Attribut cf_consumed oder
gekennzeichnet- initialisiert einen Parameter in einem direkten Aufruf einer geprüften Funktion wo Der Parameter ist nicht mit dem Attribut cf_consumed gekennzeichnet.
In Ihrem Code ist myObject
ein "beibehaltener Objektzeiger". Ein "C beibehaltener Zeigertyp" enthält void*
(dies ist eine etwas schlampige Definition, die sie als Platzhalter verwenden, da Core Foundation "Objekte" oft void*
sind).
So kann ein ObjC-Objekt implizit in ein void*
konvertiert werden, wenn es als Methodenparameter verwendet wird. In diesem Fall gibt es keine zusätzliche Speicherverwaltungssemantik (d. H. Es ist das Äquivalent von __bridge
cast). Abschnitt 7.8 warnt uns, dass void*
möglicherweise nicht so behandelt wird Zukunft, aber ich würde mir darüber keine Sorgen machen. Wenn es passiert, wird das Hinzufügen von __bridge
trivial.
Beachten Sie, dass myObject
hier nicht geschützt ist. Es liegt an Ihnen, sicherzustellen, dass es auf andere Weise beibehalten wird, bis die Animationen abgeschlossen sind, oder Sie können abstürzen.
__bridge
wird verwendet, um das Eigentumsrecht an Variablen / Referenzen (wie Retain-Anzahl) zu übergeben, das C-API für Ziel-C oder Ziel-C für API ist.
Gehen Sie durch Clangs Dokument :
Überbrückte Güsse
Ein überbrückter Cast ist ein Cast im C-Stil, der mit einem von drei Schlüsselwörtern versehen ist:
%Vor%nicht-behebbarer Zeigertyp Wenn T ein nicht zurückhaltbarer Zeigertyp ist, Dann muss op einen beibehaltenen Objekt-Zeigertyp haben. Sonst die Besetzung ist schlecht gebildet. Es gibt keine Eigentumsübertragung, und ARC fügt keine ein Operationen beibehalten. (__bridge_retained T) opt den Operanden, der den Objektzeiger-Typ beibehalten haben muss, in den Zieltyp, der sein muss ein nicht-retainable Zeigertyp. ARC behält den Wert, vorbehaltlich der übliche Optimierungen für lokale Werte, und der Empfänger ist verantwortlich zum Ausbalancieren dieses +1. (__bridge_transfer T) opt den Operanden, der einen nicht-behaltbaren Zeigertyp haben muss, auf den Zieltyp, der a sein muss beibehaltener Objekt-Zeigertyp ARC wird den Wert am Ende freigeben des einschließenden vollen Ausdrucks, vorbehaltlich der üblichen Optimierungen auf lokale Werte.
Diese Umwandlungen werden benötigt, um Objekte in und aus zu übertragen ARC-Kontrolle; Siehe die Begründung im Abschnitt über die Umwandlung von zurückhaltbare Objektzeiger.
Verwenden Sie einen __bridge_retained oder __bridge_transfer, um nur zu überzeugen ARC, um ein unausgeglichenes Zurückhalten bzw. Freigeben zu emittieren, ist schlecht form.
Jetzt,
void * t = (void *) self; // FEHLER: Besetzung von ... erfordert eine überbrückte Besetzung Warum es falsch ist, weil Sie versuchen, die Referenz von Objective-C auf C zu übertragen. Es ist nicht gelungen, die Referenz zu übernehmen.
void * t = (__bridge void *) selbst; // RICHTIG Warum es richtig ist, weil Sie Ihre Ziel-C-Referenz auf C übertragen haben. Nach dem Dokument von LLVM. Siehe oben angegebene Regeln.
%Vor% Die obigen Zeilen sind noch immer in Ordnung, weil Sie den C-Referenztypkontext anstelle von NULL
Tags und Links objective-c ios automatic-ref-counting bridge