I have an NSStatusItem with NSMenu that has a delegate. This delegate dynamically updates the menu based on several factors. Therefore, in the documentation, I use the method to quickly update the menu:
- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel;
At the appropriate time in this method, I call the following:
NSMenu *submenu = [[NSMenu alloc] init]; SomeSubmenuDelegate *submenuDelegate = [[SomeSubmenuDelegate alloc] init]; submenu.delegate = submenuDelegate; item.submenu = submenu;
The status menu is displayed correctly, and the corresponding menu items have disclosure triangles for submenus; however, the submenus do not appear when the corresponding items are highlighted, although there is the following method in SomeSubmenuDelegate, which, based on my experience, should show three empty menu items:
- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu { return 3; }
Logging does nothing, even in menuWillOpen, so it seems that the methods are never called, making me believe that somewhere the delegate is not working, or some menu is copied at run time, and the delegate is not installed in the process ..
A workaround for this is to create the entire top-level submenu of NSMenuDelegate (for the NSStatusItem menu) instead of assigning a delegate. There are several drawbacks here.
1) I save my actions in NSMenuDelegate, and it would be nice to have separate files for the parent and submenu.
2) Although this is not necessarily essential, it means that I allocate memory for each NSMenuItem submenu before it is needed.
It seems optimal, I should be able to use a delegate here, as with any other NSMenu.
Any thoughts / suggestions are welcome. The first question is for me here!
EDIT: Is it because of ARC? Perhaps I mistakenly assumed that, by convention, ARC would save the delegate object, thinking in terms of the Garbage collection, but maybe it was released because delegates are weak references, and ARC does not make such assumptions. I could find the garbage collection link in Apple docs stating that garbage collection would contain a strong link ... but obviously ARC is not garbage collection, and I cannot find any information about it. This means that I will need to keep the delegate in the parent deletion, which seems ugly for something so dynamic. Is there a way to save a delegate in ARC and then release it at the appropriate time without a link in the parent deletet (or somewhere else in this case)?