Best way to connect NSMenuItems from the Builder interface?

So, I spent some time checking CocoaDev by reading Cocoa docs on NSMenuItems and doing some tests in Interface Builder.

In my application, I have an application menu ([NSApp mainMenu]) developed in Interface Builder. I see three potential ways:

  • Put my actions in NSApplicationDelegate. This seems strange to me, partly because it is still in the food chain, partly because it seems locked up.

  • Create subtasks that will listen to various messages about NSMenuItem actions. It would seem useful, but it seems that in order to be in the chain of defendants, there may be some magic that I could not understand.

  • Create an NSObject that listens for a specific application menu, puts it in xib, and connects it. This seems to me the best solution at the moment, because I can isolate the material and not depend on the chain of the defendant to reach a specific object. BUT I am wondering, maybe when I get my application to a sufficient degree of complexity, this can be a problem, because it usurps the responder chain, which exists for some reason besides ease of use.

Sorry for the long question. Is there a preferred approach? Thanks!

+6
source share
2 answers

It really depends on the architecture of your application. As a rule, perform actions wherever they make sense. An action reporting responder chain helps you in this regard.

If your application is not document-based, the response chain for activity messages is as follows:

  • Whatever the defendant is the first defendant
  • View Hierarchy
  • Window
  • Window controller
  • Window delegate
  • NSApp
  • Application delegation

I only use actions in the application’s deletion if they are truly global for the entire application. Otherwise, I put them in a window controller (which is usually a window delegate) if they make sense for a specific window or view controller if they make sense for a specific view.

It is worth noting that view controllers (subclasses of NSViewController ) arent automatically inserted into the responder chain. I do this manually after adding the appropriate view to the supervisor. For example, in a subclass of NSViewController :

 NSResponder *nextResponder = [[self view] nextResponder]; [[self view] setNextResponder:self]; [self setNextResponder:nextResponder]; 

Inserts self (an instance of a subclass of NSViewController ) into the responder chain between the view and the original views of the next responder.

Note that there is nothing wrong with your third approach, namely the presence of a specific purpose for (a subset) of activity messages. A responder chain exists to enable various entities to process action messages because some actions may be context sensitive. For example, the actions in the File menu usually apply to the window, which is currently the main window, so it makes sense to not have a specific purpose and instead use a chain of responders. On the other hand, the actions in the ApplicationName menu are really global - they don’t need to go through the chain of responders, so you can connect them to a specific target.

+6
source

Usually I just show IBActions in the application controller ( NSApp delegate) and lay the menu items before these steps. This is a pretty standard way of doing things. If you have a lot of menu items, you can also split the functionality into one or more controllers connected to the application controller and push menu items to them.

0
source

Source: https://habr.com/ru/post/887483/


All Articles