2013-09-08 1 views
3

J'ai un NSStatusItem avec un NSMenu qui a un délégué. Ce délégué met à jour dynamiquement le menu en fonction de quelques facteurs. Donc, par la documentation, mettre à jour rapidement le menu, j'utilise la méthode:NSMenuDelegate non appelé pour sous-menu dans NSMenuItem créé par un autre NSMenuDelegate

- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel; 

Au moment opportun, dans cette méthode que j'appelle les éléments suivants:

NSMenu *submenu = [[NSMenu alloc] init]; 
SomeSubmenuDelegate *submenuDelegate = [[SomeSubmenuDelegate alloc] init]; 
submenu.delegate = submenuDelegate; 
item.submenu = submenu; 

Le menu d'état affiche correctement, et les éléments de menu appropriés ont des triangles d'affichage pour les sous-menus; cependant, les sous-menus n'apparaissent pas lorsque les éléments appropriés sont mis en évidence, même si dans la SomeSubmenuDelegate la méthode suivante existe, qui d'après mon expérience devrait montrer trois éléments de menu blanc:

- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu 
{ 
    return 3; 
} 

Exploitation forestière ne fait rien aussi bien, pas même dans menuWillOpen, il semble que les méthodes ne sont jamais appelées, ce qui me fait croire que quelque part le délégué n'est pas défini, ou le menu est copié pendant le runtime et le délégué est désactivé ...

pour créer le sous-menu entier au niveau supérieur NSMenuDelegate (pour le menu NSStatusItem) au lieu d'affecter un délégué. Il y a quelques inconvénients ici

1) Je garde mes actions dans le NSMenuDelegate, et ce serait bien d'avoir des fichiers séparés pour le parent et les sous-menus.

2) Bien que ce ne soit pas nécessairement important, cela signifie que j'alloue de la mémoire pour chaque sous-menu NSMenuItem avant qu'il ne soit nécessaire.

Cela semble optimal, je devrais être capable d'utiliser un délégué ici comme avec n'importe quel autre NSMenu.

Toutes pensées/suggestions sont grandement appréciées. Première question pour moi ici!

EDIT: Est-ce dû à l'ARC? J'ai peut-être mal supposé que, par convention, l'ARC conserverait l'objet délégué, en pensant à la récupération des ordures, mais peut-être est-il publié parce que les délégués sont des références faibles et ARC ne fait pas de suppositions comme ça. Je n'ai pu trouver que des références à la collecte des ordures dans les docs Apple, ce qui indique que la collecte des ordures conserverait une référence forte ... mais évidemment, ARC n'est pas garbage collection, et je ne trouve aucune information à ce sujet. Cela signifie que je devrais retenir le délégué dans le délégué des parents, ce qui semble laid pour quelque chose de si dynamique. Y a-t-il un moyen de retenir le délégué dans le cadre de l'ARC et de le libérer au moment opportun sans référence au délégué du parent (ou ailleurs ailleurs)?

Répondre

0

Dans mon cas, j'ai déplacé la déclaration de mon instance de menu de la méthode vers une variable membre.

de

-(void)awakeFromNIb{ 
.. 
[self setMenu:[[MyMenu alloc] init]]; 

à

@implementation MyView{ 
    MyMenu *myMenu; 
} 
-(void)awakeFromNib{ 
    ... 
    myMenu = [[MyMenu alloc]init]; 

    [self setMenu:[myMenu createMenuStructure]]; 

La méthode: 'createMenuStructure' créé localement mon menu. 'MyMenu' implémente le NSMenuDelegate.

Ceci contient la variable myMenu comme référence forte. Le gestionnaire fonctionne maintenant parfaitement.

Questions connexes