Professional Web Applications Themes

Forwarding your NSMenu message. - Mac Programming

I'm trying to find the best way to "fool" the my NSMenu to call a selector that my first responder object does not respond to, and the object is not in the responder chain. I'm trying to get my first responder object to forward the message (through forward invocation) to another object (NSObject, not a view). I know that I could just setEnabled the menu item and this would work (wouldn't it?), but the menu and the view (first responder) are in different NIB files, and you cant IBOutlet across NIBs (can I?) I've tried respondsToSelector, but this messes up ...

  1. #1

    Default Forwarding your NSMenu message.

    I'm trying to find the best way to "fool" the my NSMenu to call a selector
    that my first responder object does not respond to, and the object is not in
    the responder chain.
    I'm trying to get my first responder object to forward the message (through
    forward invocation) to another object (NSObject, not a view). I know that I
    could just setEnabled the menu item and this would work (wouldn't it?), but
    the menu and the view (first responder) are in different NIB files, and you
    cant IBOutlet across NIBs (can I?)
    I've tried respondsToSelector, but this messes up the forwardInvocation.

    Does anyone have any ideas?
    Someone must have wanted to do this before.

    Thanks a lot
    T

    Tim Guest

  2. #2

    Default Re: Forwarding your NSMenu message.

    In article <BC2B2D9C.5BC1%org>,
    Tim R Johnson <org> wrote:
     

    The simplest way to do this would be to simply implement a small forward
    method, like so:

    - (void)someThingy:sender { [hiddenObject someThingy:sender]; }

    This keeps your code nice and separate, and may make things easier to
    change in the future. The downside is that if you're forwarding fifty of
    these things, it gets annoying. But if it's just a few, this is a better
    approach.

    Another thing you can do is to keep your other object in the responder
    chain. If it's a controller, maybe it should be your NSWindow's
    delegate, which is a potential target for messages (I think).
     

    This is what you should do if you use forwardInvocation:. Generally,
    when you override forwardInvocation: to forward messages to another
    object, you should also override respondsToSelector: like this:

    - (BOOL)respondsToSelector:(SEL)sel {
    return [super respondsToSelector:sel] || [forwardingObject
    respondsToSelector:sel];
    }

    What are you doing, and what do you mean when you say it 'messes up'
    forwardInvocation:?
    Michael Guest

  3. #3

    Default Re: Forwarding your NSMenu message.

    Tim R Johnson wrote: 

    Menu actions don't necessarily have to be sent to the responder chain.
    Just set the menu's target in IB to your application delegate or any
    other object.

    -jcr
    John Guest

  4. #4

    Default Re: Forwarding your NSMenu message.

    Thanks for the responses.
    I want the target to be the "first responder" because of the nature of the
    menu, so changing the target does not help me.

    in article idiom.com, John C. Randolph at
    idiom.com wrote on 1/15/04 3:28 AM:
     
    >
    > Menu actions don't necessarily have to be sent to the responder chain.
    > Just set the menu's target in IB to your application delegate or any
    > other object.
    >
    > -jcr[/ref]

    Tim Guest

  5. #5

    Default Re: Forwarding your NSMenu message.

    The problem with forwarding the message from my responder class is that I'm
    trying for the responder class not to know about the selector directly.
    I just want the forward object to receive the events from the responder
    chain. Can I just add an NSResponder to the responder chain? How would that
    work?
     
    The problem with this (which is a pretty simple and elegant solution) is
    that I don't want my responder class to know about 'someThingy', I just want
    the menu to call someThingy in the hiddenObject directly.

    To use your example as well.. an example...

    My responder class holds a pointer to 'hiddenObject' (NSObject) as a member
    variable. HiddenObject can be one of 3 subclasses. I want those hiddenObject
    subclasses to be able to receive events sent by menus (which may be
    different between all hiddenObjects), but the responder class does not know
    about the selectors of hiddenObject.

    How can I get menus to work with hiddenObject?
    Can I add it to the responder chain?

    My forwardInvocation solution sounded good in my head, but the problem was
    with the "respondsToSelector" call. ForwardInvocation gets called when a
    class gets a message it does not respond to, but I think the "message does
    not respond to" is determined by 'respondsToSelector'.
    To get a menu item enabled automatically, one of your classes in the
    responder chain must respond to the selector associated with the menu item.
    So to enable the menu, you override respondsToSelector and pass the message
    to your hiddenObject. I.e. 
    So this all works fine, the menu item is enabled, yay. When you click the
    menu item, the message is passed to our special responder class, which it is
    checked against by "respondsToSelector". This class now responds to this
    selector (because of our overriding code), so therefore it can call
    performSelector on the class, and not forwardInvocation, except that the
    class does not really have that selector, and you get an error in the
    perform.

    How can you override respondsToSelector and use forwardInvocation at the
    same time? Am I using this all wrong? This is what it looked like to me.
    Maybe I really messed up.


    Thanks for any help :)
    Ti


    in article mail-CE7117.11003915012004localhost, Michael Ash at
    com wrote on 1/15/04 2:00 AM:
     
    >
    > The simplest way to do this would be to simply implement a small forward
    > method, like so:
    >
    > - (void)someThingy:sender { [hiddenObject someThingy:sender]; }
    >
    > This keeps your code nice and separate, and may make things easier to
    > change in the future. The downside is that if you're forwarding fifty of
    > these things, it gets annoying. But if it's just a few, this is a better
    > approach.
    >
    > Another thing you can do is to keep your other object in the responder
    > chain. If it's a controller, maybe it should be your NSWindow's
    > delegate, which is a potential target for messages (I think).

    >
    > This is what you should do if you use forwardInvocation:. Generally,
    > when you override forwardInvocation: to forward messages to another
    > object, you should also override respondsToSelector: like this:
    >
    > - (BOOL)respondsToSelector:(SEL)sel {
    > return [super respondsToSelector:sel] || [forwardingObject
    > respondsToSelector:sel];
    > }
    >
    > What are you doing, and what do you mean when you say it 'messes up'
    > forwardInvocation:?[/ref]

    Tim Guest

  6. #6

    Default Re: Forwarding your NSMenu message.

    Tim R Johnson <org> wrote:
     

    But in your other message you said you wanted the someThingy to "respond
    directly" (with no intermediary) to the menu item being chosen.

    So it must follow as the night the day, that either someThingy must be
    in the responder chain (meaning the chain of things to which
    nil-targeted messages is sent, including delegates and windowcontrollers
    and whatnot) or you must make a someThingy instance the target. How
    could there be a third alternative that satisfies both your conditions?
    Or, to put it more cogently, why do you want there to be a third
    alternative? What could there be about "the nature of the menu" that
    would require such a thing?

    It is easy to have an object behave as a oline to another object,
    but I do not know how that would fit into something as complicated as
    the responder chain for menu items, given the demands of menu validation
    and so forth. m.

    --
    matt neuburg, phd = com, http://www.tidbits.com/matt/
    AppleScript: The Definitive Guide
    http://www.amazon.com/exec/obidos/ASIN/0596005571/somethingsbymatt
    Read TidBITS! It's free and smart. http://www.tidbits.com
    matt Guest

  7. #7

    Default Re: Forwarding your NSMenu message.

    In article <BC2C8035.5C09%org>,
    Tim R Johnson <org> wrote:
     

    You could try it. Make your other object inherit from NSResponder, then
    just do [hiddenObject setNextResponder:[self nextResponder]]; [self
    setNextResponder:hiddenObject];. I'm not sure of the ramifications of
    doing something like that, though.
     

    Who is setting up these menus? From your description, it sounds like
    they're being set up at runtime. Why can't you set their target to your
    hidden object at runtime too?
     

    No, 'does not respond to' is determined by your class not having an
    entry for that selector in its method table in this case. Basically, a
    message send is translated to a call to objc_msgSend(), which performs
    the work of searching your class's method tables to find the function to
    invoke. If it doesn't find one, then it sends forwardInvocation: instead.
     
    > So this all works fine, the menu item is enabled, yay. When you click the
    > menu item, the message is passed to our special responder class, which it is
    > checked against by "respondsToSelector". This class now responds to this
    > selector (because of our overriding code), so therefore it can call
    > performSelector on the class, and not forwardInvocation, except that the
    > class does not really have that selector, and you get an error in the
    > perform.
    >
    > How can you override respondsToSelector and use forwardInvocation at the
    > same time? Am I using this all wrong? This is what it looked like to me.
    > Maybe I really messed up.[/ref]

    What kind of error do you get? [obj
    performSelector:selector(objDoesNotUnderstandThis )] should trigger your
    forwardInvocation: just like a regular method call. Have you read the
    section on Forwarding in The Objective-C Programming Language? It may be
    useful to you, I'm not sure, it's here:

    http://developer.apple.com/doentation/Cocoa/Conceptual/ObjectiveC/4obj
    c_runtime_overview/chapter_4_section_3.html#//apple_ref/doc/uid/20001425/
    TPXREF109
    Michael Guest

Similar Threads

  1. Forwarding to URL
    By Craig N in forum Macromedia Flash
    Replies: 0
    Last Post: August 26th, 12:52 AM
  2. delete forwarding message copy
    By Jean-Louis Vill in forum Linux Setup, Configuration & Administration
    Replies: 3
    Last Post: September 9th, 04:22 AM
  3. X forwarding
    By John Salvo in forum Sun Solaris
    Replies: 5
    Last Post: July 18th, 11:30 AM
  4. IP forwarding
    By cyborg in forum Windows Networking
    Replies: 0
    Last Post: July 6th, 02:18 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139