(Einsteiger-) Fragen ohne Zusammenhang

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

  • a) Nein, im -awakeFromNib müssen die Objekte bereits initialisiert sein, auch die nicht persistenten Instanzvariablen. Außerdem weißt du nicht, ob du aus einem Nib kommst oder nicht.

    b) Das ist mir bekannt. Sie sagen es aber nicht an der Stelle, an der es um Initialisierung geht. Und zwar der generellen Initialisierung innerhalb von Objective-C. Es ist ja schön ein grundlegendes Dokument zu haben, welches mit langen Erläuterungen eine eherne Regel aufstellt, wenn dann irgendwo anders im Dickich ohne Hinweis bei den Grundlagen etwas anderes gemacht wird. Dann muss man zumindest mmall dranschreiben: Ach, übrigens, beim Coding kann das anders sein.

    c) Wieso möchtest du das nicht?
    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"?
  • Zu a)
    Nun ja, ich weiß aber schon, ob meine Klasse aus einem Nib per -initWithCoder: erzeugt wird oder nicht, denn dafür muss ich ja eine IB Palette schreiben, sonst kann ich ein Objekt ja gar nicht voll initialisiert im Nib ablegen. D.h. Du must die -encodeWithCoder: Methode sowieso entsprechend implementieren.

    Zu b)
    Die -initWithCoder: Methode kommt übrigens aus dem NSCoding-Protokoll und daher kann man sie auch nicht einfach mit den anderen init-Methoden in einen Topf werfen. Sie hat halt eine ganz spezielle Aufgabe, nämlich ein Objekt aus archivierten Daten zu initialisieren.

    Zu c)
    Na ja, ich fände eine Objekterzeugung wie zum Beispiel sowas

    Quellcode

    1. [[NSButton alloc] initWithFrame:frame
    2. frameRotation:0.0
    3. allowsMixedState:NO
    4. alternateImage:altImage
    5. alternateTitle:@""
    6. attributedAlternateTitle:nil
    7. attributedTitle:nil
    8. bezelStyle:aStyle
    9. borderd:NO
    10. buttonType:aButtonType
    11. image:anImage
    12. imagePosision:aPosition
    13. keyEquivalent:@""
    14. keyEquivalentModifierMask:aMask
    15. periodicDelay:aDelay
    16. interval:anInterval
    17. showsBorderOnlyWhileMouseInside:NO
    18. sound:aSound
    19. state:NSOffState
    20. title:@"Press me"
    21. titleWithMnemonic:@"Press me"
    22. transparent:YES
    23. action:@selector(anAction:)
    24. alignment:NSCenterTextAlignment
    25. baseWritingDirection:NSWritingDirectionNatural
    26. cell:aButtonCell
    27. continuous:NO
    28. enabled:YES
    29. font:aFont
    30. formatter:nil
    31. ignoresMultiClick:YES
    32. refusesFirstResponder:NO
    33. tag:0
    34. target:theTargetObject
    35. autoresizesSubviews:NO
    36. autoresizingMask:rezisingMask
    37. bounds:frame
    38. boundsRotation:0.0
    39. focusRingType:NSFocusRingTypeDefault
    40. hidden:NO
    41. nextKeyView:nil
    42. postsBoundsChangedNotifications:NO
    43. postsFrameChangedNotifications:NO
    44. toolTip:@"Press the button"
    45. interfaceStyle:NSMacintoshInterfaceStyle
    46. menu:nil
    47. nextResponder:nextResponder];
    Alles anzeigen
    doch ein wenig unhandlich. Und das ist noch nicht einmal alles, was man an einem NSButton so einstellen kann. So ein Ding für NSTableView oder NSTextView mag ich mir gar nicht erst vorstellen.

    Michael
  • a) Ich muss gerade in den Fällen der Ableitung keine Palette schreiben. Aber davon unabhängig muss ich nicht zweimal dden gleichen Code im dI und im -initWithCoder: haben. Wieso sollte ich das müssen. Das führt nur zu Wartungsproblemen.

    b) Jeder -init… hat eine ganz spezielle Aufgabe, sonst gäbe es ihn ja nicht. Ich sagte ja schon: Meinetwegen sollte man es halten wie der Dachdecker, wobei ich das unpüraktisch finde. Nur darf ich dann nicht die Regel aufstellen: "Immer den eigenen dI aufrufen" und mich dann später selber nicht daran halten. Gerade bei so einem allgemeinen Protokoll hätte es sich angeboten zu sagen: "Neben dem dI gibt es noch die Initialisierung aus einem Archiv. Hier läuft das anders."

    c) Die Objekterzeugung ist nicht unhandllicher als der Aufruf der Setter für jeden Parameter. Der Decoder sieht dann so aus (natürlich mit decode-Aufrufen):

    Quellcode

    1. [self setFrame:frame
    2. [self setFrameRotation:0.0
    3. [self setAllowsMixedState:NO
    4. [self setAlternateImage:altImage
    5. [self setAlternateTitle:@""
    6. [self setAttributedAlternateTitle:nil
    7. [self setAttributedTitle:nil
    8. [self setBezelStyle:aStyle
    9. [self setBorderd:NO
    10. [self setButtonType:aButtonType
    11. [self setImage:anImage
    12. [self setImagePosision:aPosition
    13. [self setKeyEquivalent:@""
    14. [self setKeyEquivalentModifierMask:aMask
    15. [self setPeriodicDelay:aDelay
    16. [self setInterval:anInterval
    17. [self setShowsBorderOnlyWhileMouseInside:NO
    18. [self setSound:aSound
    19. [self setState:NSOffState
    20. [self setTitle:@"Press me"
    21. [self setTitleWithMnemonic:@"Press me"
    22. [self setTransparent:YES
    23. [self setAction:@selector(anAction:)
    24. [self setAlignment:NSCenterTextAlignment
    25. [self setBaseWritingDirection:NSWritingDirectionNatural
    26. [self setCell:aButtonCell
    27. [self setContinuous:NO
    28. [self setEnabled:YES
    29. [self setFont:aFont
    30. [self setFormatter:nil
    31. [self setIgnoresMultiClick:YES
    32. [self setRefusesFirstResponder:NO
    33. [self setTag:0
    34. [self setTarget:theTargetObject
    35. [self setAutoresizesSubviews:NO
    36. [self setAutoresizingMask:rezisingMask
    37. [self setBounds:frame
    38. [self setBoundsRotation:0.0
    39. [self setFocusRingType:NSFocusRingTypeDefault
    40. [self setHidden:NO
    41. [self setNextKeyView:nil
    42. [self setPostsBoundsChangedNotifications:NO
    43. [self setPostsFrameChangedNotifications:NO
    44. [self setToolTip:@"Press the button"
    45. [self setInterfaceStyle:NSMacintoshInterfaceStyle
    46. [self setMenu:nil
    47. [self setNextResponder:nextResponder];
    Alles anzeigen

    Wo liegt da der Vorteil?
    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"?
  • Original von Tom9811
    Im Übrigen entspricht es dem Konzept des designated Initalizers, welches nicht von mir, sondern von Apple stammt:
    "Designated initializers are chained to each other through messages to super, while other initialization methods are chained to designated initializers through messages to self."
    Und man kann ja schon erwarten, dass sich Apple an seine eigenen Regeln hält.

    Ich habe mal überlegt, was passieren würde, wenn Apple es so machen würde, wie Du es Dir vorstellst.

    -initWithCoder: ruft den designated Initializer auf, soweit gut.
    Wie da oben steht ruft dieser den designated Initializer von super auf, auch noch gut.
    -initWithCoder: ruft -initWithCoder: von super auf, damit auch super seinen Kram dekodieren kann!
    -initWithCoder von super ruft dann den eingenen designated Initializer auf, aber halt, der wurde bereits schon einmal durch die Subklasse aufgerufen.

    Nein, das geht so gar nicht.

    Michael
  • Original von Tom9811
    c) Die Objekterzeugung ist nicht unhandllicher als der Aufruf der Setter für jeden Parameter.
    [...]
    Wo liegt da der Vorteil?

    Der Vorteil liegt in der Vererbung. In meiner Subklasse muss ich nur selbst definierten Parameter setzen. Die geerbten Parameter lasse ich von der -initWithCoder: Methode der Superklasse setzen. Einem allumfassenden Initializier müsste ich aber ausnahmslos alles übergeben.

    Michael
  • Der dI muss nicht allumfassend sein. Das finde ich positiv, hat aber mit diesem Problem nichts zu tun. Du sollst nur das, was der dI nimmt, sei es viel, sei es wenig, anstatt mit Settern zu setzen mit ihm setzen.

    Das erspart dir doppelte Logik. Doppelte Logik ist fehleranfällig.

    Und wie gesagt: Man kann es ja noch halten wie der Dachdecker, auch wenn ich es nicht gut finde. Aber dann darf man eben nicht eine abweichende allgemeine Regel sprechen und Wasser trinken.
    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"?
  • Wenn es Apple so machen würde, wie ich es mir vorstelle, würde in der Doku stehen:"Die Initialisierung beim Decoding funktioneirt übrigens anders." Es wäre auch schon dienlich, wenn der Decoder einfach nicht -initWithCoder: heißen würde. Dann käme man nämlich nicht auf den Gedanken, dass er sich nicht an diie Initialisierungregeln hält.

    Aber das Problem im Initialisierungsablauf sehe ich in der Tat. In der Tat ist es einem Initialisierer verboten einen Initialisierer der Superklasse aufzurufen, es sei denn dI den di(super). Auch so eine "eherne Regel" von Apple. Ein weiteres Argument, es so nicht zu machen. (Das ist übrigens einer der Gründe, warum das Apple verbietet.)

    Das wäre unpraktisch, ohne jeden Zweifel. Deshalb sollte man dann eben den Decoder ganz aus der Initialisierunjg herausnehmen. Ihn nicht Initializer nennen, ihn nicht -init nennen usw. Kein Mensch würde sich mehr vertun. Dieses Thema haben wir ja heute wahrlich nnicht zum ersten Male.
    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"?
  • Wenn der dI nicht allumfassend sein muss, hast Du ja wieder das ursprüngliche doppelte Setzen von Parametern. Erst mit Standardwerten per dI und dann mit den Werten aus dem Archiv. Dazu dann noch das doppelte Aufrufen der dI der Superklassen -> Verschlimmbesserung hoch 2.

    Man kann auch einfach -initWithCoder: als designated Initializer für archivierte Objekte ansehen und schon stimmt Apples Regel wieder zu 100%. :]

    Michael
  • An eine Ausrede-Lösungmit einem Schatten-DI habe ich auch schon gedacht. Nur steht das nun wirklich nirgendwo. Im Übrigen vermittelt die Doku mindestens dein Eindruck, dass es stets einen dI pro Klasse gibt. Aber auch diese Regel wird ja ohnehin nicht durchgehalten, siehe etwa NSCell.

    Nochmal: Man kann das ja halten wie der Dachdecker. Aber ein Hinweis in der Objective-C-Doku wäre notwendig. Das ist wie gesagt nicht der erste Thread zu diesem Thema.
    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"?
  • Wenn Du die Einstellungen über NSUserDefaults verwaltest, ist das nicht möglich, denn sobald Du Änderungen an den Standard User Defaults vornimmst, musst du davon ausgehen, dass diese auf Platte geschrieben werden. Das geschieht nämlich in regelmäßigen Abständen automatisch.

    Was Du vorhast, kannst Du durch Verwendung von NSUserDefaultsController erreichen. Den kann man so konfigurieren, dass Änderungen nicht sofort gespeichert werden und bietet auch eine -revert: Methode an.

    Michael
  • Ok, ich bastle immer noch an dem hier rum. Jetzt such ich nach einem weg, die aktiven Ecken auszuschalten. Mein "Plan" ( ;) ) : Dock-Preferences oeffnen: Ecken speichern, neue Werte reinschreiben und am Schluss wieder aufraeumen. Jetzt nuetzt mir das nichts, wenn Dock das zeugs nicht liest, was ich da reinschreibe. Ginge ja auch mit "kill <dockid>" aber sieht fuer mich nicht wirklich nach ner sauberen Loesung aus...
    Gruss Dominik.