ARC: weak erst ab iOS 5?

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • ARC: weak erst ab iOS 5?

    Guten Tag alle miteinander.
    Momentan plagt mich eine Frage, für die ich anscheinend zu dumm bin zu suchen.
    Und zwar benutze ich in meinem Projekt ARC und möchte ios ab der Version 4.3 unterstützen.
    Laut einigen Tutorials im Netz sollte man lieber weak statt strong für Propertys benutzen, da weak die Objekte bei Nichtbenutzung auf nil setzt und somit Speicherlecks unterbunden werden.
    Allerdings meine ich irgendwo gelesen zu haben, dass weak erst ab ios 5 funktioniert. Ist das wirklich so?

    Ich meine, der eigentliche Unterschied zwischen weak und strong ist doch nur, dass weak das Objekt auf nil setzt, strong hingegen nicht. Wieso sollte es dann erst ab ios 5 funktionieren?
    Vielleicht hat jemand hier im Forum eine Ahnung, was denn nun Sache ist und was nicht?

    Vielen Dank!
  • Das ist doch seine Antwort: weak erst in iOS 5.

    Wenn du nicht weißt, was mit Ownership gemeint ist, solltest du ARC erst einmal links liegen lassen und die Grundlagen des Memory Managements lernen.
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • @Lucas de Vil
    Irgendwie habe ich das so im Kopf, dass unter non ARC das Reference Counting über retain erfolgt (Zähler um Eins erhöht wird). Das Objekt wird erst deallociert, wenn der Reference Count auf 0 steht.
    Assign hingegen wird bei primitiven Datentypen eingesetzt, dort erfolgt kein Reference Counting (bitte berichtige mich wenn ich damit falsch liege).

    Nun soll doch bei ARC das strong retain ersetzen, und weak alle assigns.
    Wenn ich aber nun bei ios 4.3 kein weak benutzen kann, wie soll ich dann primitive Datentypen anlegen? Alle als strong?
  • Primitive Datentypen haben nichts mit den Speicherverwaltungstypen bzw. dem Reference Counting zu tun. Strong, weak, assign und retain sind nur für Objective-C-Klassen und Tool-Free-Bridged Datentypen interessant.

    Wenn Du weak nicht verwenden kannst, dann nimm assign. Ansonsten solltest Du Dir den Rat von Lucas zu Herzen nehmen.
    „Meine Komplikation hatte eine Komplikation.“
  • Hm habe mir mal diesen Erklärungsversuch angesehen: iosguy.com/2010/09/04/understanding-memory-management/
    Dort ist beschrieben, dass ich ein Objekt besitze, wenn ich es selbst erzeuge, kopiere oder anfordere. Im Grunde ist es nur ein retain auf dieses Object (der Retain Count wird um eins erhöht).
    Sobald ich es frei lasse (release) bin ich nicht mehr der Besitzer dieses Objekt, und jemand anders kümmert sich darum. Soweit alles klar.

    Wenn ich nun aber in einem Scope (etwa einer einfachen Funktion) ein Objekt nur über einen Pointer benutze, bin ich nicht der Besitzer des Objekts. Somit laufe ich gefahr, dass das Objekt irgendwann nicht mehr existent sein kann.
    Es ist dann also eine "weak refrence", also eine schwache Verbindung.

    Das bedeutet für mich also:
    Wenn eine Property ein Objekt halten soll (besitzen), benutze ich retain (strong bei ARC). Dies ist der Fall, wenn ich das Objekt selber erzeuge, kopiere oder von irgendwo her bekomme.

    Wenn eine Property nur auf ein Objekt zugreifen soll, benutze ich assign (weak bei ARC in ios 5, oder unsafe_unretained alles < ios 5). Also lege ich das Obejtk nicht selber an, kopiere es nicht und bekomme es auch nirgendwo her. Ich zeige nachher nur auf eins.

    Ist das soweit korrekt? Kann doch nicht so schwer sein ;)
  • miro schrieb:

    Wenn eine Property ein Objekt halten soll (besitzen), benutze ich retain (strong bei ARC). Dies ist der Fall, wenn ich das Objekt selber erzeuge, kopiere oder von irgendwo her bekomme.

    Falsch. ;)
    developer.apple.com/library/ma…/Articles/MemoryMgmt.html
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • miro schrieb:

    ...Laut einigen Tutorials im Netz sollte man lieber weak statt strong für Propertys benutzen, da weak die Objekte bei Nichtbenutzung auf nil setzt und somit Speicherlecks unterbunden werden.
    Allerdings meine ich irgendwo gelesen zu haben, dass weak erst ab ios 5 funktioniert. Ist das wirklich so?

    Primärquelle benutzen (Apple-Doku)! Bringt auf lange Sicht mehr, als Tutorials irgendwo im Netz flüchtig zu lesen. Früher (tm) hätte man einfach RTFM gesagt, aber diese Zeiten sind zum Glück lange vorbei... :D
  • macmoonshine schrieb:

    Es gibt Fälle, in denen weak gegenüber strong zu bevorzugen ist; z. B. bei Nicht-Toplevelobjekten in Storyboards / XIBs. Daraus jedoch eine allgemeingültige Regel herzuleiten, ist Unsinn.

    Auch Retain-Cycles erkennt nur der, der sich mit dem Memory Management beschäftigt hat. +g+
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Also wer wann ein Objekt besitzt ist ja einfach:

    Immer wenn ich retain benutze, bin ich der oberste Owner in der RetainCount Kette.
    Immer wenn ich ein Objekt kopiere, bin ich der Owner des Kopierten Objekts (nicht der Owner des zu kopierenden Objekts).
    Immer wenn ich ein Objekt erzeuge (alloc init) dann bin ich der Owner des Objekts.
    Dies alles sind dann sogenannte "strong references" also starke referenzen.

    Nun versteh ich aber die Sache mit dem assign noch nicht so ganz. Das sind ja "schwache Referenzen", also welche die nicht durch retain, copy oder alloc erzeugt wurden.
    Wann bzw. wie werden denn diese schwachen Referenzen eingesetzt? Bzw. wieso sollte ich mit schwachen Referenzen arbeiten, wenn ich doch eh an einem Objekt rumfummeln will?

    Das Einzige was ich mir darunter vorstellen kann ist ein Array mit Objekten.
    Ich greife auf ein Objekt in dem Array zu (etwa NSSTring *meinString = [meinArray objectAtIndex:5]). Somit wäre doch meinString eine schwache Referenz auf das Objekt oder? Berichtigt mich bitte wenn ich damit falsch liege.
  • miro schrieb:

    Wann bzw. wie werden denn diese schwachen Referenzen eingesetzt? Bzw. wieso sollte ich mit schwachen Referenzen arbeiten, wenn ich doch eh an einem Objekt rumfummeln will?

    Auch das steht in dem von mir verlinkten Dokument unter 'Practical Memory Management: Use Weak References to Avoid Retain Cycles' :P
    Den String aus deinem Beispiel benutzt du ja gar nicht, was solltest du also damit?
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • miro schrieb:

    Ist je egal was ich dannach mit dem mache, aber es ist doch dann eine weak reference soweit ich das verstehe.

    Ob eine Referenz strong oder weak ist, hängt nicht von der Methode ab, die Dir ein Objekt liefert, sondern von der Deklaration der Variable/Property. Unter ARC ist strong die Defaultdeklaration, d.h. Bei Deinem Beispiel

    NSString *meinString = [meinArray objectAtIndex:5];

    ist meinString eine strong Reference auf das Objekt. Der Compiler sieht die Zeile so, als hättest Du

    __strong NSString *meinString = [meinArray objectAtIndex:5];

    geschrieben und mach daraus prinzipiell folgendes:

    NSString *meinString = [[meinArray objectAtIndex:5] retain];

    Michael
  • @michael
    Super erklärt! Danke für die Info.

    Habe mittlerweile auch nochmal in mein ios Buch geschaut und nun weiss ich fast worum es geht.
    Wenn eine property als retain gekennzeichet wird, übernimmt sie die Verantwortung für das übergebene Objekt in der setter Methode.
    Bei copy hingegen wird das übergebene object nicht retaint, sondern das kopierte in der setter Methode.

    Bei einer property die als assign gekennzeichnet ist, wird scheinbar weder retain, noch copy oder sonst irgendwas gemacht. Es erfolgt eine einfache Zuweisung in der setter Methode. Allerdings verstehe ich nicht so ganz wofür das gut sein soll. Immerhin weiß der compiler dann nicht, dass meine property auf dieses objekt zeigt. Dieses verfluchte assign ist es, was mir zu schaffen macht. Retain zu verstehen ist ja kein Hexenwerk, aber was macht dieses blöde assign und wozu soll ich das benutzen? In meinem Buch steht, dass man assign für nicht-Objekte verwendet oder wenn zwei Objekte sich gegenseitig retainen um nicht in den Retain-Cycle zu kommen. Allerdings scheint das nur eine blöde Faustformel zu sein.

    Es muss doch ein programmatisches Beispiel zu assign geben, ähnlich wie dein beispiel zu retain.