Korrekte init implementierung

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

  • Amin Negm-Awad schrieb:

    Nein, in 3 kann eine andere Instanz derselben Klasse oder einer Subklasse geliefert werden. Es wäre ein Verstoß von -init (super), ein klassenfremde Objekt zu liefern. -init (super) verspricht einfach eine initialisierte Instanz der Klasse – nicht mehr und nicht weniger. Darauf kann ich mich verlassen und das ist okay.

    Du hast eine Klasse A mit einer Subklasse B und C. [A init] liefert unter bestimmten Umständen eine Instanz von B. Wenn du jetzt in init von C "self = [super init]" machst kann es sein dass der Code aus Klasse C versucht ein Objekt der Klasse B zu initialisieren. Und das dürfte in so gut wie allen Fällen ein Fehler sein.

    Amin Negm-Awad schrieb:

    Und es ist außerordentlich praktisch, die Instanz austauschen zu können. Etwa bei Immutables und bei Twintones. Da kannst du nämlich im +alloc noch nicht feststellen, ob du eine neue Instanz brauchst.Du nennst ja selbst das Beispiel.

    Jetzt mache mal den Twintone. Wie willst du denn in +alloc testen, ob der Twintone schon da ist, wenn du noch gar nicht weißt, was du im initWith…: bekommst?
    Hab ich doch gar nichts dagegen. Das ist eine praktische Sache. Nur wenn man eine neue Klasse von so einer Klasse ableitet muss man eben genau darauf achten, was man in -init tut. In so einem Fall wird das übliche "self = [super init]; if (self) { ... }; return self;" nicht zum gewünschtem Ergebnis führen.
  • Nein, in deinem Beispiel verstößt -init (A) gegen den Vertrag, siehe Dokumentation.

    Es ist auch gar kein Problem für A, eine C zu instantieren. Dazu existiert [[self class] alloc].

    Bei Class-Clustern kann es zu Problemen kommen. Das ist aber das Problem der Superklasse. Es ist auch ihre Verantwortung. Wenn du self nicht zuweist, kann übrigens die Superklasse gar nichts machen. Das ist garantiert weniger mächtig.

    Aber sei's drum: Shipleys Aussagen waren schon immer ganz gewiss eine Verletzung des Vertrages. Nunmehr ist dies auch ausdrücklich dokumentiert. Da verbietet sich jede Diskussion. Soll er sich halt sein eigenes Cocoa bauen.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • dergraf schrieb:

    Amin Negm-Awad schrieb:

    Nein, in 3 kann eine andere Instanz derselben Klasse oder einer Subklasse geliefert werden. Es wäre ein Verstoß von -init (super), ein klassenfremde Objekt zu liefern. -init (super) verspricht einfach eine initialisierte Instanz der Klasse – nicht mehr und nicht weniger. Darauf kann ich mich verlassen und das ist okay.

    Du hast eine Klasse A mit einer Subklasse B und C. [A init] liefert unter bestimmten Umständen eine Instanz von B. Wenn du jetzt in init von C "self = [super init]" machst kann es sein dass der Code aus Klasse C versucht ein Objekt der Klasse B zu initialisieren. Und das dürfte in so gut wie allen Fällen ein Fehler sein.

    Amin Negm-Awad schrieb:

    Und es ist außerordentlich praktisch, die Instanz austauschen zu können. Etwa bei Immutables und bei Twintones. Da kannst du nämlich im +alloc noch nicht feststellen, ob du eine neue Instanz brauchst.Du nennst ja selbst das Beispiel.

    Jetzt mache mal den Twintone. Wie willst du denn in +alloc testen, ob der Twintone schon da ist, wenn du noch gar nicht weißt, was du im initWith…: bekommst?
    Hab ich doch gar nichts dagegen. Das ist eine praktische Sache. Nur wenn man eine neue Klasse von so einer Klasse ableitet muss man eben genau darauf achten, was man in -init tut. In so einem Fall wird das übliche "self = [super init]; if (self) { ... }; return self;" nicht zum gewünschtem Ergebnis führen.


    warum sollte eine Klasse eine Subclasse von sich selbst zurückliefern?
    Die Subklasse sollte die klasse ja gar nicht kennen!
  • Amin Negm-Awad schrieb:

    Nein, in deinem Beispiel verstößt -init (A) gegen den Vertrag, siehe Dokumentation.

    Es ist auch gar kein Problem für A, eine C zu instantieren. Dazu existiert [[self class] alloc].

    Bei Class-Clustern kann es zu Problemen kommen. Das ist aber das Problem der Superklasse. Es ist auch ihre Verantwortung. Wenn du self nicht zuweist, kann übrigens die Superklasse gar nichts machen. Das ist garantiert weniger mächtig.

    Aber sei's drum: Shipleys Aussagen waren schon immer ganz gewiss eine Verletzung des Vertrages. Nunmehr ist dies auch ausdrücklich dokumentiert. Da verbietet sich jede Diskussion. Soll er sich halt sein eigenes Cocoa bauen.
    Wie wäre es, wenn du mal diesen ominösen Vertrag vorzeigst, von dem du die ganze Zeit redest. Wenn in meinem Beispiel -init (A) dagegen verstößt dann verstoßen auch sämtliche init...-Methoden von NSString dagegen. Keine einzige davon liefert eine Instanz von NSString. Und wenn ich eine Subklasse von NSString erstelle, dann ist das sehr wohl mein Problem und nicht das Problem von NSString.

    Fakt ist und bleibt folgendes: Wenn "self != [super init]" ist habe ich ein Problem. Was dann genau zu tun ist hängt von super ab.
  • dergraf schrieb:

    Amin Negm-Awad schrieb:

    Nein, in deinem Beispiel verstößt -init (A) gegen den Vertrag, siehe Dokumentation.

    Es ist auch gar kein Problem für A, eine C zu instantieren. Dazu existiert [[self class] alloc].

    Bei Class-Clustern kann es zu Problemen kommen. Das ist aber das Problem der Superklasse. Es ist auch ihre Verantwortung. Wenn du self nicht zuweist, kann übrigens die Superklasse gar nichts machen. Das ist garantiert weniger mächtig.

    Aber sei's drum: Shipleys Aussagen waren schon immer ganz gewiss eine Verletzung des Vertrages. Nunmehr ist dies auch ausdrücklich dokumentiert. Da verbietet sich jede Diskussion. Soll er sich halt sein eigenes Cocoa bauen.
    Wie wäre es, wenn du mal diesen ominösen Vertrag vorzeigst, von dem du die ganze Zeit redest. Wenn in meinem Beispiel -init (A) dagegen verstößt dann verstoßen auch sämtliche init...-Methoden von NSString dagegen. Keine einzige davon liefert eine Instanz von NSString. Und wenn ich eine Subklasse von NSString erstelle, dann ist das sehr wohl mein Problem und nicht das Problem von NSString.

    Fakt ist und bleibt folgendes: Wenn "self != [super init]" ist habe ich ein Problem. Was dann genau zu tun ist hängt von super ab.
    Der Vertrag steht

    a) in der Doku und wurde von mir zitiert

    b) ergibt sich aus dem Rückgabewert, der nicht void ist.


    Er steht übrigens auch in der Doku zu -init:
    […]In some cases, an init method might release the new object and return a substitute. Programs should therefore always use the object returned by init, and not necessarily the one returned by alloc, […]


    Und auch die andere Seite der Vereinbarung:
    Every class must guarantee that the init method either returns a fully functional instance of the class or raises an exception.


    Hier sind die Quotations durcheinander gekommen. (Ist das ne Beta?)

    Gritsch:
    warum sollte eine Klasse eine Subclasse von sich selbst zurückliefern?
    Die Subklasse sollte die klasse ja gar nicht kennen!

    ----
    Muss sie auch nicht, siehe oben: [[self class] alloc].
    Das ist eben nicht dasselbe wie [BaseClass alloc].
    Video ansehen

    Sie will die Instanz austauschen. Also muss sie allozieren. Dazu muss sie die richtige Klasse verwenden.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?

    Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von Amin Negm-Awad ()