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

  • miro schrieb:

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

    Nun, es gibt eben nicht nur Objekte, sondern auch skalare Datentypen (int, float, double, NSInteger, Strukturen wie CGRect, CGSize, ...). Für alle diese Datentypen braucht man assign, weil skalare Datentypen keine Methoden kennen. Stell dir vor, Du schreibst eine Klasse für eine komplexe Zahl. Die Deklaration könnte so aussehen:

    Quellcode

    1. @interface ComplexNumber : NSObject
    2. @property (assign) double re;
    3. @property (assign) double im;
    4. - (ComplexNumber *)complexNumberByAddingComplexNumber:(ComplexNumber *)cn;
    5. ...
    6. @end

    Michael
  • @michael
    Genau das habe ich doch vorher schon gefragt, ob man assign nur bei primitiven Datentypen verwendet (damit meinte ich Skalare datentypen, war mir nicht bewusst dass das so heisst).

    Wenn es also so ist wie du sagts, lautet die Regel für assign: Assign nur bei propertys benutzen, die keine Objekte sondern skalare Datentypen entgegen nehmen. Einfacher gesagt: assign nur bei "primitiven" Datentypen. Alles andere retain.
  • miro schrieb:

    Wenn es also so ist wie du sagts, lautet die Regel für assign: Assign nur bei propertys benutzen, die keine Objekte sondern skalare Datentypen entgegen nehmen. Einfacher gesagt: assign nur bei "primitiven" Datentypen.

    Richtig.

    miro schrieb:

    Alles andere retain.

    Mit ARC nimmt man strong statt retain. Das ist aber identisch. „Alles andere“ ist aber auch ungenau ausgedrückt. Man nimmt strong, wenn man die Eigentümerschaft benötigt (was meistens der Fall ist).
    Es gibt aber Fälle, da muss man die Eigentümerschaft nicht übernehmen, wie zum Beispiel bei Outlets auf Subviews, weil die Subviews durch ihre Superviews „am Leben gehalten“ werden und ohne Superview auch die Subviews in der Regel nutzlos sind.
    Dann gibt es noch den Fall, wo man retain-cycles vermeiden muss und deshalb auch die Eigentümerschaft nicht übernehmen darf. Klassisches Beispiel Delegation, wo sich immer zwei Objekte gegenseitig referenzieren. Für diese Fälle ist weak gedacht. weak ist ein „intelligentes“ assign wo die Referenz auf nil gesetzt wird, wenn das referenzierte Objekt aus dem Speicher gelöscht wird. Das funktioniert aber nur mit der passenden Objective-C Runtime, die es erst ab iOS 5.0 und OS X 10.7 gibt. Unter iOS 4.x und OS X 10.6.x muss man deshalb statt weak das unsafe_unretained nehmen. unsafe_unretained ist identisch mit assign, sagt dem Programmierer aber klar und deutlich „hier droht Gefahr durch einen Dangling Pointer“.

    Michael
  • @michael
    das war die beste erklärung die ich überhaupt im netz und in meinem buch dazu finden konnte. wirklich hut ab, man merkt dass du ahnung von der materie hast und du kannst es gut rüber bringen. solltest lehrer werden für sowas!

    aber eine frage habe ich noch, könntest du mir ein programmatisches beispiel für ein einfachen retain-cycle geben?
  • Das war die Antwort auf deine Frage...

    Etwas bildlicher dargestellt:

    C-Quellcode

    1. // Buch.h
    2. @property (retain) Autor *autor;

    C-Quellcode

    1. // Autor.h
    2. @property (retain) Buch *buch;

    C-Quellcode

    1. // AppDelegate.h
    2. Autor * lucas = [[Autor alloc] initWithName:@"Lucas"]; // lucas RC=1 wegen -init*
    3. Buch * diary = [[Buch alloc] initWithTitle@"Tagebuch"]; // diary RC=1 wegen -init*
    4. [lucas setBuch:diary]; // diary RC=2 wegen -retain im Setter, sieht man hier aber nicht.
    5. [buch setAutor:lucas]; // lucas RC=2 wegen -retain im Setter, sieht man hier aber nicht.
    6. [lucas release]; // lucas RC=1...
    7. [buch release]; // diary RC=1...


    Beide Objekte halten sich gegenseitig fest und keines erreicht jemals einen RC von 0 (sprich: keines verliert jemals seinen letzten Besitzer).

    Wenn du versuchst, das so nachzubauen um dir den RC anzusehen, wird es übrigens nicht dem hier skizzierten entsprechen.
    Zwischendurch kann sich noch sonstwas an das Objekt hängen. Du weißt z.B. nicht, ob -retainCount im Getter noch irgend ein -retain auf das Objekt setzt, um zu vermeiden, dass drei Millisekunden vor der Ausgabe das Objekt freigegeben wird.
    «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