Posen & Co.

  • RE: Posen & Co.

    Jo, das hat bei mir auch etwas gedauert, bis ich den OP verstanden habe, weil es ja "eigentlich" ganz anders ist, nämlich so, dass man beim Posing keine neuen Members haben darf.

    Und bei genauer Betrachtung ist es in der Tat so, dass er die Membervariablen nicht in der posierenden Klasse anlegt, sondern in der Basisklasse. Er will sich einfach die unbekannte Basisklasse nachbilden. Mit Posing hat das nichts zu tun.
    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"?
  • RE: Posen & Co.

    Original von hns
    Ja Deine eigene Klasse. Aber wenn ich das Problem richtig verstehe nicht die, für die sie sich ausgibt.

    *sing* aber die superklasse stammt von NSObject ab *sing*

    Original von Tom9811
    Hattest du nicht mal behauptet, dass das Textsystem unbrauchbar, weil für deine Zwecke zu langsam sei?

    Drum hab ich's ja auch verschnellert.

    Anscheinend will keiner die Frage verstehen oder es kann keiner beantworten. Da muss ich wohl dumm sterben.
  • RE: Posen & Co.

    Original von Tom9811
    Und bei genauer Betrachtung ist es in der Tat so, dass er die Membervariablen nicht in der posierenden Klasse anlegt, sondern in der Basisklasse. Er will sich einfach die unbekannte Basisklasse nachbilden. Mit Posing hat das nichts zu tun.

    Redest du über mich?
    Ich bilde mir überhaupt nichts nach. Ich kopiere mir das Interface der vorhandenen klasse, weil ich keinen Header dafür habe, mache eine subklasse und pose die subklasse als die super. Was ist denn daran bitte so schwer zu verstehen???
  • RE: Posen & Co.

    Der LayoutManager ist kein View. Du denkst dir immer was aus und stellt irgendwelche behauptungen auf. Ich bin aber der Meinung, dass der LayoutManager eher zum View bzw. zum Controller gehört als irgendwo anders hin. Der hat mit einem Model rein gar nix zu tun.

    Wieso hat meine Implementierung nichts mit posing zu tun? Ich bilde nichts nach.

    Auh egal jetzt. Ich lasses. Ist wie immer total sinnlos und hirnverbrannt, mit dir über irgendwas reden zu wollen.
  • RE: Posen & Co.

    Jepp, das gilt vor allem, wenn du das Problem hast. Dir ist jetzt aber schon aufgefallen, dass *alle* das Problem in deinem Missverständnis sehen?

    ALLES SCHLAMPEN AU?ER MUTTI!!!!!!!!!
    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"?
  • RE: Posen & Co.

    Ok, dann erkläre mir mein Misverständnis. Ich erkläre dir deins:

    Ich habe nichts weiter gemacht, als mir den Header mittels Class-Dump aus dem AppKit zu holen. Die Klasse aus dem App-Kit stammt von NSObject ab. Dann habe ich diesen Header in mein Programm kopiert und abgeleitet. Die abgeleitete Klasse habe ich implementiert und dann per poseAsClass: über die andere posiert. Du bist immernoch der meinung, dass ich etwas nachgebildet hätte. Aber das habe ich nicht. Ich habe ausschließlich meinem Programm diese Klasse bekannt gemacht. Ein Header ist nichts anderes als ein bekanntmachung. Ich habe rein gar nichts implementiert.
  • RE: Posen & Co.

    a) Nein, ein Header ist etwas anderes als eine Bekanntmachung. Das versuchen wir dir jetzt aber schon seit zwei Tagen zu erklären und scheitern damit offenbar.

    b) Kopieren ist nachbilden.

    c) Du musst die Members angeben, weil du *nachbildest*, wobei es völlig gleichgülltig ist, ob du das kopieren, nachbilden oder rosa Unterhose nennst.

    d) Du musst die Members nicht angeben, weil du posierst.

    Es ist aber auch müßig. Du hattest 3 Wochen Crashs am Hut, nicht ich.
    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"?
  • RE: Posen & Co.

    Original von M.A.X
    Ok, dann erkläre mir mein Misverständnis. Ich erkläre dir deins:

    Ich habe nichts weiter gemacht, als mir den Header mittels Class-Dump aus dem AppKit zu holen. Die Klasse aus dem App-Kit stammt von NSObject ab. Dann habe ich diesen Header in mein Programm kopiert und abgeleitet. Die abgeleitete Klasse habe ich implementiert und dann per poseAsClass: über die andere posiert. Du bist immernoch der meinung, dass ich etwas nachgebildet hätte. Aber das habe ich nicht. Ich habe ausschließlich meinem Programm diese Klasse bekannt gemacht. Ein Header ist nichts anderes als ein bekanntmachung. Ich habe rein gar nichts implementiert.

    Genau das ist ja der Fehler...

    Man darf anscheinend nur eine Subklasse der Originalklasse posen und nicht eine andere, die zufällig ebenfalls von NSObject abgeleitet ist.

    => probiere es mal zweistufig:

    @interface MeineNachbildungDerKlasse : NSObjekt
    {
    ... Variablen laut ClassDump
    }
    @end

    @interface MeineKlasseDieIchAlsMeineSuperKlassePosenWerde : MeineNachbildungDerKlasse
    @end

    Einen Unterschied macht das z.B. bei [super dealloc]...

    -- hns
  • RE: Posen & Co.

    So hab ich das doch gemacht. Ich habe die originalklasse genommen. Und eine weitere, eine subklasse dieser, erstellt. Nochmal der code aus dem ersten post:

    Quellcode

    1. @interface NSUndoTextOperation : NSObject
    2. {
    3. struct _NSRange _affectedRange;
    4. NSUndoManager *_undoManager;
    5. NSLayoutManager *_layoutManager;
    6. }
    7. - (id)initWithAffectedRange:(NSRange)affectedRange layoutManager:(NSLayoutManager *)layoutManager undoManager:(NSUndoManager *)undoManager;
    8. - (void)undoRedo:(id)sender;
    9. - (NSTextView *)firstTextViewForTextStorage:(NSTextStorage *)storage;
    10. - (NSUndoManager *)undoManager;
    11. - (BOOL)isSupportingCoalescing;
    12. @end
    13. @interface _NSUndoTextOperation : NSUndoTextOperation
    14. @end
    Alles anzeigen


    Max
  • RE: Posen & Co.

    Ok. Hatte ich schon nicht mehr in Erinnerung - sorry.

    Die Frage war ja eigentlich:
    Es müssen also im *Interface* alle Variablen der zu überposenden klasse bekannt sein. Dass man keine hinzufügen kann ist mir klar, aber vielleicht kann mir einer der Obj-C geeks sagen, warum die bekannt sein müssen? Wird die größe der Klasse nicht zu Laufzeit, sondern schon beim Compilieren ermittelt?


    Eigentlich ist das egal - denn Du musst die Variablen ja irgendwie bekannt machen.

    Wenn es der Compiler macht: dann musst Du ihm die Variablen angeben.
    Wenn es zur Laufzeit geschieht, dann muss das Laufzeitsystem die Variablen kennen um die Größen zusammenzuzählen. Und die Annahme, dass sich die Größtenberechnung auf die Originalklasse und nicht die selbst definierte, geposte Klasse bezieht trifft offenbar nicht zu.

    Vielleicht folgende Überlegung: poseAs: überschreibt auch -alloc. Und der nimmt die Größe von Instanzen der *aktuellen* Klasse.

    -- hns
  • RE: Posen & Co.

    Das hat er ja gemacht.

    Nochmal:

    Du hast eine x-beliebige Klasse K. Von der kannst du eine Subklasse K' machen und _nur diese_ (keine weiteren Subklassen von K') dürfen als K posen. Dabei dürfen *keine* Members hinzugefügt werden. K' muss exakt die gleichen Members haben wie K. Wenn du also ableitest, *muss* das Interface von K' *leer* bleiben (bezüglich der Instanzvariablen).

    Er hat eine Klasse K aus dem System genommen, ohne den Header zu haben. Diese hat Member. Seine Posing-Klasse muss also *eben genau diese Member haben*. Wenn er jetzt aber K (als Prothese für System-K) leer lässt und K' leer lässt, dann hat K' *keine* Member. Wenn jetzt K' für System-K posiert, sind die Anzahl der Member *unterschiedlich*.

    Das muss krachen.

    Das Problem liegt nicht im Posieren, sondern darin, dass er die Klasse unvollständig nachbildet.

    Davon unabhängig gibt es zwei Klassen mit gleichen Namen im Laufzeitsystem. Du weißtja nicht, wer wie wann wo die Klassenobjekte erzeugt. In Cocoa gibt es jedenfalls irgendwo diese Klasse. In seiner Source gibt es diese Klasse. Da kann man ja vllt noch den Linker austricksen.

    Da aber bei Objective-C Klassen immer ein Klassenobjekt haben, existieren auch die Klassenobjekte zweimal. Ich glaube nicht, dass die RTE darauf Rücksicht nimmt, dass ein Singleton nun zweimal existiert.

    Oder eben nur einmal. Aber welche Version dann? Das ist die Kombi von einer undokumentierten Klasse mit einem undokumentierten Verhalten.
    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"?
  • RE: Posen & Co.

    Hmmm.

    Was ich noch nicht ganz verstehe ist, warum es dann zur Laufzeit zwei Klassen mit selbem Namen geben soll. Eine Klasse wird doch eigentlich erst durch die Implementation definiert. Das heißt, die Implementation bekommt die Information über die Variablen aus dem Interface, was sie durch den Header einbindet. Wenn ich jetzt aber in meinem Programm von der Kopie von der Klasse keine Implementierung habe, dann existiert diese Klasse bei mir im Programm ja auch nicht. Sie ist nur definiert.

    Habt ihr mal versucht, eine Klasse nur zu definieren und nicht zu implementieren. Also legt mal einen Header an, denkt euch eine Klasse aus und nutzt diesen Header von irgendwo. Dann führt das Programm aus. Da kommt eine Laufzeitwarnung "unknown class".
  • RE: Posen & Co.

    Nochwas: Wenn ich diese Klasse bei mir definiere und den Header dann einbinde, ist es *exakt* das selbe, als würde ich den Header (wenn er public wäre) aus dem AppKit einbinden. Das kann gar nicht sein, dass die Klasse zweimal existeirt, wenn sie keine Implementation hat...
  • RE: Posen & Co.

    s/definieren/deklarieren

    Es mag auch sein, dass es da nur einmal gibt (letzter Absatz). Das spielt keine Rolle. Du hast einmal das Dingens bei dir in der Source. Einmal irgendwo in Cocoa. Du hast keinerlei Verbindung dazwischen. Du *hoffst*, dass das irgendwie gut geht.

    Du hast auch immer eine Implementierung, wenn du mindestens von NSObject ableitest. Sogar wenn du @implementation leer lässt, gibt es ja was.

    Wenn du aber ohnehin andere Interfaces hast, kann das erst recht nicht gut gehen.
    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"?
  • RE: Posen & Co.

    Wenn Die Klasse nicht zur Laufzeit gebaut wird, ja.

    Ansonsten: Nein!

    +++
    Grundsätzlicher:
    Klassen sind alleine für den Compiler interessant. Sprachen wie C++, die keine Klassenobjekte kennen, müssen zur Laufzeit nichts von der Klasse wissen, wenn man es nicht zum debuggen braucht. Dier erzeugen maximal noch ne vtable und das war es.

    In Objective-C ist das aber ambivalent. Der Klasse als Source-Code Dingens steht spiegelbildlich ein Klassenobjekt zur Laufzeit gegenüber. Wenn du die Klasse aus der Source hat, wird der Compiler an etwa 1273631287 Stellen Code erzeugen, der davon ausgeht, dass das Laufzeit-Panton übereinstimmt.

    Wird das Klassenobjekt indessen dynamisch erzeugt, so kannst du so ziemlich ganz in die Röhre schauen.

    Um das herauszufinden, müsste man in die RTE schauen und zudem am besten ein bisschen in den Cocoa-Sourcen. Beides habe ich jedenfalls nicht. (Gibt es das Dingens eigentlich in GnuStep?)

    +++
    NSUndoText* hat jedenfalls nichts gefunden.
    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"?
  • RE: Posen & Co.

    Ich bezweifle, dass NSUndoTextOperation dynamisch zur Laufzeit erzeugt wird, sonst würde Class-Dump sie ja nicht finden. Das setzt glaub ich ne komplette Implementierung vorraus.

    Womit eigentlich klar wäre, dass die Hauptklasse nur einmal existiert. Eine bekanntmachung in einem Header in meinem Programm tut da nichts verändern. Sämtliche Informationen über die Klasse könnte sich die Funktion zum Posen doch aus der Laufzeit holen. Ah, jetzt hab ich's. Hehe.

    Du hattest es (zugegebenermaßen etwas umständlich) gesagt: Da meine Subklasse, die dann posieren soll, die selbe größe wie die zu überposende Klasse haben muss, muss für die Kompilierung der SUBklasse die Größe der anderen bekannt sein. Das hat also überhaupt nichts mit dem Header, dynamsichen Erzeugungen udn irgendwelchen Doppelten erscheinungen zu tun. Es geht nur um die Größe der posierenden Klasse. Und die muss ja gleich sein. Der Compiler kann es in meinem Programm nicht wissen. Das Probelm kann somit erst zur Laufzeit auftreten. Gut :)

    Das wirft noch eine Frage auf: warum darf eine posenden Klasse nicht kleiner sein? Also größer ist klar, weil die Instanzen mehr Platz brauchen würden. Und kleiner könnte ich mir noch so erklären, dass die erzeugten instanzen kleiner sind, als eigentlich notwendig und die überposte klasse somit auf nicht alloziierten Speicher zugreift.

    Doch noch eine Frage: warum crsht es dann an ganz anderen Enden des Porgramms, sogar in anderen Threads? Wenn auf nicht bessenen Speicher zugegriffen wird, dann müsste es doch sofort bei der erstellung einer instanz crashen...
  • RE: Posen & Co.

    Den ersten Teil hatte ich vor Ewigkeiten (in Forenmaßstäben ohne Berücksichtigung von Josef) gesagt. Der Rest bezog sich nicht auf deine ursprüngliche Frage, sondern war ein *zusätzlicher* Hinweis auf die Gefahren, die du selbst bei ordnungsgemäßter Kopie hast. Der Anlass war das "Jetzt funktioniert es ja" oder so ähnlich.

    Sie darf auch nicht kleiner sein, weil etwa der Compiler verschiedene Angaben für das Laufzeitsystem vorbereitet, etwa die Offsets für die Instanzvariablen. Hast du weniger, so fehlen die. Wir können beide nicht sagen, was dann passiert. Ebenso kann es bei der Allozierung Probleme geben.

    In solchen Fällen crasht es fast nie definiert.

    a) Auf den korrupten Teil muss nicht sofort zugegriffen werden.
    b) Es wird kaum so sein, dass die RTE exakt für jede Instanz Speicher vom System anfordert. Vielmehr wird das in Blöcken gemacht. Daher können etwa auch Elemente eines C-Arrays "gehören", wenn du über das Ende hinausläufst.
    c) Möglicherweise -warhscheinlich beim endlichen Crash- befiondet sich da etwas anderes. Das zerstörst du. Eine Zeitlang kann das gut gehen. Irgendwann wird das wichtig.
    d) Stelle dir nur vor, dass nach jeder internen Speicheranforderung in Manier einer verketteten Liste der nächhste _interne_ Block adressiert wird. Bei einem alloc schaut er etwa nach, wo der nächste interne freie Speicher in dem vom System gelieferten Block liegt. Hast du da etwas zerbritzelt, fällt das dann auf. Muss aber auch nicht. Hast du es so zerbritzelt, dass es etwas auf den ersten Blick gültiges herauskommt, fängt er vllt nur an, jetzt etwqasa anderes zu zerbritzeln. Das möglicherweise ...
    e) Jeder Zeiger, gleich für was, führt zu einem Fernzerbritzeln. Das kann Ewigkeiten dauern, bis dann etwass crasht. Zu debuggen ist das fast gar nicht.

    MAW: Wenn du nicht sicher weißt, was da läuft, kannst du gar nicht sagen, was passiert.
    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"?