views:

350

answers:

2

I'm new to Obj-C/Cocoa programming, and I'm having an issue trying to dynamically add menu items to an NSMenu instance and have the items action selector already set upon insertion.

I can, add the dynamic menu items fine, but the action selector doesn't trigger when the item is clicked via the menu.

The first line below is the line of code I am using to add the menu item. You can set I'm setting the action:(SEL)aSelector to the "openEchowavesURL" function.

This function is in the same controller class file and I've included the function definition below.

Am I just calling the wrong selector syntax or someting? Or what is the trick to get the menu item to call a selector when clicked?


[statusMenu insertItemWithTitle:[NSString stringWithFormat:@"%d - %@", convo.newMessagesCount, convo.ewName] action:@selector(openEchowavesURL:) keyEquivalent:@"" atIndex:0];

- (void)openEchowavesURL:(id)sender {
    // function details here
}
A: 

Actions need a target or else they get sent to nil and then new rules apply.

Azeem.Butt
can you explain that a bit more? I don't think I follow. I set the action to the selector I want on the menu item being inserted.What else do I need to do regarding setting a target?
cpjolicoeur
Send the item a setTarget message.
Azeem.Butt
+2  A: 

If you want the action to be triggered against your object, you have to specify a target for the new NSMenuItem:

NSMenuItem *item = [statusMenu insertItemWithTitle:[NSString stringWithFormat:@"%d - %@", convo.newMessagesCount, convo.ewName] action:@selector(openEchowavesURL:) keyEquivalent:@"" atIndex:0];
[item setTarget:self]; // or whatever target you want

If you don't do it, then the NSResponder chain will be walked until an object responds to the selector.

Laurent Etiemble
thanks. So, if the chain is walked, then why is the selector not found in my current controller class? Why do I need to manually specify self in that case?
cpjolicoeur
You have to meet certain criteria in order to be queried during search. I suggest you to read the following guide to understand how: http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/EventOverview/index.html#//apple_ref/doc/uid/10000060i
Laurent Etiemble
Your controller is probably not a part of the responder chain.
Azeem.Butt
Classes generally are not control targets anyway. Responders are instances. Your object may respond to the selector, but if it isn't in the responder chain and you don't set the control's target specifically to your object, then the message will never hit your object. The solution is either to make your object a responder and keep it in the responder chain, or set the control's target to your object.
Peter Hosey