Controller-Methode, die normalerweise von einem Button aufgerufen wird, händisch aufrufen

  • Original von hns
    NSCFNumber ist eine interne Klasse die auf Core-Foundation-Objekte abbildet. Wenn da irgendwo etwas in der Doku von "toll-free-bridged" steht, dann ist das gemeint. NSCFNumber ist eine Unterklasse von NSNumber und versteht alle deren Methoden (und keine andere). D.h. der Fehler ist ein anderer.

    OK, daß ich ein NO bekomme, wenn ich auf die Klassenzugehörigkeit frage, finde ich äußerst unschön, aber dann frage ich halt nach der Methode.

    Was mich allerdings stutzig macht ist, daß dieses NSCFNumber auf respondsToSelector:@selector(selectedTag) mit YES reagiert, es aber letztlich doch nicht kann.

    Schon mal den Debugger ausprobiert, einen Breakpoint auf eine Action-Methode gesetzt und im Single-Step durch den Code gelaufen?

    Ja, aber ich stehe mit dem Debugger derzeit noch etwas auf dem Kriegsfuß, aber es wird. Da habe ich noch nichts herausgefunden, außer obiges (das aber eher weniger mit dem Debugger).
  • -[NSCFNumber selectedTag]: selector not recognized

    Edit: Fhlermeldung ist nicht Code.
    Wenn Du ein 'richtiges' Objekt aufrufst, ist in 'NSNumber' die Methode 'selectedCell' nicht implementiert.

    Was Du willst, -scheint-

    Quellcode

    1. [sender intValue];
    zu sein.
    I would be embarrassed if they did not spy on me.
  • Aber woher weiß ich, auf welche Methoden dann das NSCFNumber noch reagiert.

    Du fordert ein NSNumber an, dann werden die Methoden von NSNumber implementiert. Daher weißt du das.

    Irgendwie macht es für mich keinen Sinn. Wieso kann ich jetzt nicht (so wie du es ja selbst in deinem Beispiel genannt hast), einfach auf die Klassenzugehörigkeit zu NSNumber prüfen?

    Wie kommst du darauf, dass du das nicht mehr kannst.

    Die von einem Class-Cluster meist zurückgelieferten Instanzen sind von Subklassen. -isKindOfClass testet auch auf Subklassen und liefert daher YES. Wenn es sich nicht um eine Subklasse handelt, dann tut sie so. Dafür gibt es in der Run-Time Möglichkeiten.

    Du musst dich vom Klassendenken lösen. Objective-C ist dynamisch und schwach typisiert.

    Wenn ich auf NSCFNumber teste, dann ist sie nicht bekannt (Compiler-Fehler).

    NSCFNumber ist undokumentiert, wie du selbst gesehen hast. Dahr sollst unnd darfst du nicht hierauf testen.

    Bei Java kann ich mich darauf verlassen, daß ein Integer ein Integer ist.

    Bei Objective-C kannst du dich daruf verlassen, dass +alloc, -init (NSNumber) ein Objekt zurückliefert, weches das Interface von NSNumber implementiert. Was kümmert dich da die Klasse?

    Wieso geht es hier nicht?

    Weil das so gewollt ist.

    Wo liegt darin der Vorteil/Sinn?

    Optimierung durch Spezialisierung.

    Und vor allem, wie gehe ich nun damit um?

    Du behandelst die zurückgelieferte INstanz als NSNumber.

    Irgendwie muß ich ja testen, um was es sich beim Sender handelt.

    [anObject isKindOfClass:[NSNumbre class]]
    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"?
  • Das wird ein wenig unübersichtlich:
    Hast Du die Anregung:
    Original von WoSoft
    das tag ist vom Typ int. Schreibt man z.B. so:

    Quellcode

    1. int aTag = [[sender selectedCell] tag];

    aufgenommen?
    I would be embarrassed if they did not spy on me.
  • Aber eben genau das

    Quellcode

    1. [sender isKindOfClass:[NSNumber class]]

    liefert mir NO, dabei übergebe ich doch ein NSNumber.

    Statt dessen liefert mir

    Quellcode

    1. [sender respondsToSelector:@selector(selectedTag)]

    YES. Allerdings versteht das Objekt diese Nachricht dann doch nicht (was mich nicht wirklich wundert).
  • Ich gehe davon aus, dass du dich völlig vergaloppiert hast. Das mag seine Ursache darin finden, dass da noch Grundlagen zu Objective-C fehlen. Bei einem Control als Sender ist exakt dies das erwartete Verhalten, denn ein Control ist keine NSNumbre, implementiert jedoch die Methode -selectedTag.

    Hast du eine NSNumber übergeben (was ich aus oben genannten Gründen ohnehn nicht tun würde, aber gut), dann ist -isKindOfClass ganz gewiss YES und die Frage nach dem Selektor wird ganz gewiss verneint.

    Poste noch einmal deinen Coed hier:
    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"?
  • OK, hier der Aufruf:

    Quellcode

    1. [target enterNumber:[NSNumber numberWithInt:bla]];

    target ist mein RPNController, die Klasse, die mein Controller/Model aus dem MVC darstellt.

    Hier (in meinem RPNController) frage ich ab, wer die Methode aufgerufen hat. Wenn ich die entsprechenden Tasten auf meiner GUI drücke, funktioniert das auch (else-Zweig).

    Quellcode

    1. - (IBAction)enterNumber:(id)sender {
    2. int tag;
    3. if ([sender isKindOfClass:[NSNumber class]]) tag = [sender intValue];
    4. else if ([sender respondsToSelector:@selector(selectedTag)]) tag = [sender selectedTag];
    5. ...

    Wenn ich aber den oben genannten Aufruf tätige (mit NSNumber als Übergabe), dann liefert mir das erste if NO und das zweite YES (ohne das das Objekt aber wirklich diese Nachricht versteht).

    Ich hab absolut keine Ahnung, warum sich das so verhält, wie es sich verhält.
  • Original von longW
    Stimmt.
    Es muss dann sogar ein 'control' sein.

    Quellcode

    1. NSLog(@"%@",[sender debugDescription]);

    Wieso bekomme ich vom Compiler die Warnung, daß er die Methode nicht kennt, es aber zur Laufzeit funktioniert (falls <NSMatrix: 0x33ec60> die korrekte Ausgabe ist)?
  • 'NSMatrix' scheint richtig zu sein.

    Eine ganz andere Frage:

    Quellcode

    1. int main(int argc, char *argv[])
    2. {
    3. //return NSApplicationMain(argc, (const char **) argv);
    4. NSAutoreleasePool * arp = [[NSAutoreleasePool alloc] init];
    5. ...

    Warum hebelst Du das alles aus?
    Normalerweise, insbesondere als Anfänger, schreibt man nichts in 'main'.
    I would be embarrassed if they did not spy on me.
  • Ich habs jetzt mit

    Quellcode

    1. [sender respondsToSelector:@selector(intValue)]

    gemacht und es funktioniert, wie ich es möchte.

    Aber mich würde dennoch interessieren, warum es nicht mit

    Quellcode

    1. [sender isKindOfClass:[NSNumber class]]

    funktioniert und warum die Frage nach

    Quellcode

    1. [sender respondsToSelector:@selector(selectedTag)]

    positiv verläuft, was eigentlich nicht sein dürfte.
  • Original von longW
    Warum hebelst Du das alles aus?
    Normalerweise, insbesondere als Anfänger, schreibt man nichts in 'main'.

    Ich weiß, aber das erschien mir als die schnellste Möglichkeit nur mal kurz was an meiner RPNProtocol-Klasse auszuprobieren. Dafür brauchte ich die GUI nicht und ich hätte weit mehr schon mal anpassen müssen.
  • Von irgendwo ruft ein 'NSMatrix'-Objekt die Methode auf, kann daher nur aus dem 'nib' stammen.
    Wahrscheinlich geistert das 'nib' noch herum, weil es mit eingebaut wird (und das wird es in dem Beispiel), GUI hin oder her.
    I would be embarrassed if they did not spy on me.
  • Original von longW
    Von irgendwo ruft ein 'NSMatrix'-Objekt die Methode auf, kann daher nur aus dem 'nib' stammen.
    Wahrscheinlich geistert das 'nib' noch herum, weil es mit eingebaut wird (und das wird es in dem Beispiel), GUI hin oder her.

    Ah, ich hab das mit der NIB getestet. Meinen zusätzlichen Code in der main.m war dazu deaktiviert. Sorry, falls ich hier für irritation sorge. :D
  • Original von Tom9811
    Aber nebenbei: Der Sender sollte auch keine NSNumber sein. Das geht zwar, ist jedoch schräg. Besser wäre es, wenn du eine weitere Controller-Schicht einziehst.

    Ich kann mich ja irren, aber war das nicht dein erster Lösungsvorschlag (13.05.2007 13:36)? ;)

    Oder wie wäre es, wenn ich NSNumber über eine Kategorie die Methode selectedTag beibringe? Zu dreckig? Irgendwie mag ich den Gedanken mehr, als für jede Action-Methode noch eine weitere Methode zu bauen. :)

    Allerdings ist mein Problem, warum mein NSNumber-Object auf respondsToSelector:@selector(selectedTag)] mit YES reagiert, immer noch nicht geklärt.
  • Ich kann mich ja irren, aber war das nicht dein erster Lösungsvorschlag (13.05.2007 13:36)?
    Du irrst dich:
    Ich wäre das Problem in der Tat anders angegangen und hätte die Action-Schicht von der funktionallen getrennnt.Die Action-Methoden häztten dann nur durchgereicht. Aber gut, dass wirst du jetzt nicht mehr ändern können.
    Es kommt selten vor, dass ich meine Vorschläge nicht mehr kenne.
    +++
    NSNumber antwortet nicht auf -seletedTag. Wie ich bereits ausführte, scheint bei dir etwas gänzlich im Argen zu liegen.
    Oder wie wäre es, wenn ich NSNumber über eine Kategorie die Methode selectedTag beibringe? Zu dreckig?

    Es ist nicht der Sinn der Sache. Wenn man am Sinn der Sache vorbeiprogrammiert, gibt es $IRGENDWANNEINMAL Ärger.

    Irgendwie mag ich den Gedanken mehr, als für jede Action-Methode noch eine weitere Methode zu bauen. :)

    Actions jsind die Verbindung zum Interface und gehören originär zum Controller. Die Ausführung einer Methode, die das Model verändert, ischeint (ich kenne deine Software nicht im Einzelnen) originär zum Model zu gehören.

    Du wirst diese Methoden an mutmaßlich 24387923487 verschiedenen Stellen deiner Applikation aufrufen wollen. Sie funktionieren gänzlich ohne Bezug zum UI. Mir scheint es daher krude, die Funktionalität in einer Methode unterzubringen, die die Verbindung zum UI herstellt.

    Es gibt übrigens Parameter-Bindings. Aber ads führt jetzt viel zu weit.
    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
    NSNumber antwortet nicht auf -seletedTag. Wie ich bereits ausführte, scheint bei dir etwas gänzlich im Argen zu liegen.

    Was ja auch korrekt ist, da es keine selectedTag-Methode in NSNumber gibt. Allerdings tut es so, auf vorherige Nachfrage, als könne es das.

    Actions jsind die Verbindung zum Interface und gehören originär zum Controller. Die Ausführung einer Methode, die das Model verändert, ischeint (ich kenne deine Software nicht im Einzelnen) originär zum Model zu gehören.

    Naja, bei einem Taschenrechner ist das Model ja so klein, daß es doch vertretbar ist, Controller und Model zusammenzuführen, oder besser doch nicht?

    Es gibt übrigens Parameter-Bindings. Aber ads führt jetzt viel zu weit.

    Naja ein Stichworte mehr kannst du ja trotzdem fallen lassen... Das gehört zum Thema Cocoa-Bindings?
  • Aber ich werde mich nachher man dransetzen und den Controller und Model zu trennen. Dabei kann ich ja dann auch gleich die von dir vorgeschlagene Zwischenschicht einziehen.

    Auf jeden Fall schon mal ein großes Danke für die Antworten. :)