Was ist __bridge ?

  • Was ist __bridge ?

    Hi,

    ich wollte gerade einen NSAlert als Sheet erstellen und da ich den für mehrere Abfragen benutzen möchte, wollte ich ihm im ContextInfo einfach einen String mitgeben, damit ich dann im alertDidEnd: entsprechend die benötige Methode aufrufen kann. Wenn ich nun also

    Quellcode

    1. -(viod)deleteAlert:(NSString *)deleteType
    2. {
    3. NSAlert *alert=[NSAlert alertWithMessageText:NSLocalizedString(@"Warning", @"Delete alert title") defaultButton:NSLocalizedString(@"Ok", @"Delete alert ok button") alternateButton:NSLocalizedString(@"Cancel", @"Delete alert cancel button") otherButton:nil informativeTextWithFormat:NSLocalizedString(@"This cannot be undone!", @"Delete alert text")];
    4. if(alert)
    5. {
    6. [alert beginSheetModalForWindow:self.window modalDelegate:self didEndSelector:@selector(deleteAlertDidEnd:returnCode:contextInfo:) contextInfo:(void *)deleteType];
    7. }
    8. return;
    9. }


    mache und versuche im DidEnd: dann diesen Kontext wieder zurück zu casten

    Quellcode

    1. - (void) deleteAlertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
    2. {
    3. NSString *type=(NSString *)contextInfo;
    4. }


    dann meckert der Compiler, dass er einen Bridge cast benötigt und fügt automatisch einen

    Quellcode

    1. - (void) deleteAlertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
    2. {
    3. NSString *type=(__bridge NSString *)contextInfo;
    4. }


    ein. Was aber bedeutet das ?

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Danke euch beiden.

    Aber so ganz kapieren tue ich das nicht. Der neue NSString ist doch eh nur eine lokale Methodenvariable. Der muss es doch total egal sein ob der zugewiesene Wert weak oder strong ist. Die ist nach dem Verlassen der Methode ja eh wieder weg.

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Ohne ARC wird beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo: sicherlich ein retain an contextInfo schicken, damit das Objekt nicht zwischendurch verloren geht.

    Nach Aufruf des didEndSelector: wird ohne ARC dann sicherlich auch ein release auf contextInfo folgen, da das Objekt dann ja nicht mehr benötigt wird.

    Warum LLVM/ARC da dann jetzt einen speziellen bridged cast benötigt weiss ich jedoch auch nicht.

    Ich sagte es ja bereits: ARC verwirrt mich aktuell mehr als es mir nützt. Von daher verwende ich es aktuell noch nicht. Mit MRC habe ich aktuell keine Probleme.
  • Thallius schrieb:

    Der neue NSString ist doch eh nur eine lokale Methodenvariable.

    Der ARC-Compiler muss aber wissen, wie er damit umgehen soll. Z. B.:

    Quellcode

    1. - (NSString *)string {
    2. return (NSString *)CFStringCreate...;
    3. }

    Der String aus der CF-Funktion gehört der Methode. Der ARC-Compiler weiß das aber nicht, deswegen musst Du ihm über

    C-Quellcode

    1. return (__bridge_transfer NSString *)CFStringCreate...;
    mitteilen, dass er sich darum kümmern muss. Analog kannst Du ihm über __bridge_retained mitteilen, dass Du die Halterschaft an eine CF-Variable abgeben willst:

    Quellcode

    1. CFString *theString = (__bridge_retainded CFString *)inString;
    2. ...
    3. CFRelease(theString);

    Mit __bridge sagst Du ihm, dass alles so bleibt, wie es ist.
    „Meine Komplikation hatte eine Komplikation.“
  • Das ist unabhängig von CF. Das gilt auch, wenn Du auf void * oder irgendwas anderes castest. Die Frage ist ja: Wer gibt die Referenz frei, der ARC-Compiler oder Du? Woher soll der ARC-Compiler wissen, dass die Methode die Referenz nach dem Cast nicht selber verwaltet?

    Du kannst sie ja wieder in einen id-Pointer umwandeln und ihr ein release schicken.
    „Meine Komplikation hatte eine Komplikation.“
  • So schön der ARC ist, aber alles easy iss anscheinend doch nicht.
    Ich kannte bridge auch nicht.
    Wenn ich mich selber um die Verwaltung kümmere, hab ich das Theater nicht. Weiß nicht ob das alles so toll ist, was Apple da inzwischen macht.
  • Aus dieser Antwort:


    NSString and CFStringRef are "Toll free bridged", meaning that you can simply typecast between them.

    CFStringRef aCFString = (CFStringRef)aNSString;
    NSString *aNSString = (NSString *)aCFString;

    If you are using ARC, the new casting syntax for this case is now

    NSString *aNSString = (__bridge NSString *)aCFString
    Gruss zuko
  • wolf_10de schrieb:

    Wenn ich mich selber um die Verwaltung kümmere, hab ich das Theater nicht.

    Viel Aufregung um wenig: So oft braucht man das nicht. Und wenn man es braucht, liest man sich die Doku dazu durch. Und wenn man dazu zu faul ist, befolgt man die Vorschlge, die Xcode macht. Ich kenne bislang keinen Fall, wo die falsch waren.

    wolf_10de schrieb:

    Weiß nicht ob das alles so toll ist, was Apple da inzwischen macht.

    Ich finde ARC einen ziemlichen Fortschritt. Aber wie das mit den neuen Sachen ist: Wat dr' Buur nitt kennt, ... ;)
    „Meine Komplikation hatte eine Komplikation.“
  • "Viel Aufregung um wenig: So oft braucht man das nicht. Und wenn man es braucht, liest man sich die Doku dazu durch. Und wenn man dazu zu faul ist, befolgt man die Vorschlge, die Xcode macht. Ich kenne bislang keinen Fall, wo die falsch waren."
    finde ich auch.

    Kam früh mit dem Adressbook-Framework und __bridge in Kontakt und die werden einfach nicht jedes Framework umgestellt haben und wenn es doch läuft, ist es gut.

    ARC und SB haben die Programmierung erheblich erleichtert und ARC hat leider ein neues Problem geschaffen: Kein Newbie wird sich ernsthaft mit Speicherverwaltung auseinandersetzen wollen. Und wenn so mancher hier ehrlich ist, würde er es auch nicht mehr machen, wenn er am Anfang seines Programmiererdaseins stünde.
    Und wenn die "Alten" noch so viel meckern. Ist halt so.
    Ob es gut, schlecht oder was auch immer ist, mag dahingestellt sein, wenn ich mir meine Absturzkönige so betrachte (Payback, ReaddleDocks und einige mehr) dann kochen auch Vollprofis nur mit Wasser.

    Es ist eine Brücke und stabil ist sie auch, also gehe ich drüber.

    Liebe Grüße
    Karin
  • Ich mache gerade mein erstes größeres Projekt in ARC und ich muss sagen ich sehe die große Erleichterung einfach nicht. Wenn ich konsequent meine retain/copy properties mit self.property initialisiere und zuweise und im dealloc oder eben im viewDidUnload oder wo auch immer es wichtig ist direkt beim Anlegen der Property auch den self.property=nil eintippe, dann kann mir nichts passieren.

    Das ist also eine Zeile mehr tippen, dafür habe ich die komplette Kontrolle.

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Sehe ich auch so, ich weiß was ich anlege und wieder frei zu geben habe.
    Es geht gar nicht mal da drum, das alles Neue "scheiße" ist, sondern was zum Teufel ist __bridge ?
    Weiß nicht ob es das einem Newbie einfacher macht, wenn er sieht, dass Xcode da irgendwas hin schreibt und er auf einmal bemerkt, dass es sowas wie Speicherverwaltung gibt.
  • viewDidUnload

    … ist übrigens deprecated (ich hab' auch ganz schön geguckt, als ich das gesehen habe).
    ARC gegenüber bin ich auch sehr skeptisch: Die Grundidee ist zwar gut, aber das ganze __bridge, __weak und __strong finde ich komplizierter als meinen Speicher von Hand zu verwalten.
    Etwas polemisch ausgedrückt: Objective-C wird in Richtung "Idiotenkompatibilität" weiterentwickelt, und darunter "leiden" die Fortgeschrittenen, die es auch ohne ARC hinbekommen haben, die an sich einfachen Regeln zur Speicherverwaltung einzuhalten.
    Sicher, jeder vergisst ab und an mal einen release-Aufruf, aber wäre es denn so schlimm, wenn der Compiler diese Fehler offen im Quelltext korrigieren würde, statt im Verborgenen Methodenaufrufe zu synthetisieren und nachher wegzuoptimieren?

    Da fällt mir ein:
    Mir ist schon mehrfach aufgefallen, dass Xcode sich bei neuen Projekten nicht so wirklich darum schert, wenn man kein ARC möchte - das Template geht trotzdem direkt mit einem @autorelease los. Hat dazu schon jemand einen Bugreport verfasst?
  • t-no schrieb:

    Mir ist schon mehrfach aufgefallen, dass Xcode sich bei neuen Projekten nicht so wirklich darum schert, wenn man kein ARC möchte - das Template geht trotzdem direkt mit einem @autorelease los. Hat dazu schon jemand einen Bugreport verfasst?

    @autoreleasepool funktioniert ja auch ohne ARC. Apple schreibt dazu:
    This syntax is available in all Objective-C modes. It is more efficient than using the NSAutoreleasePool class; you are therefore encouraged to adopt it in place of using the NSAutoreleasePool.

    Ein Bugreport ist also nicht nötig und würde wohl mit „works as intended“ geschlossen werden.

    Michael

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Michael ()