Je conserve du code hérité et lorsque je l'ai compilé avec le SDK 10.8 plutôt qu'avec le SDK 10.7, des raccourcis équivalents clés pour certains éléments de menu cessé de travailler. Mon hypothèse est que c'est parce que ces éléments de menu sont dans un état désactivé. Les NSMenuItems qui ne fonctionnent plus sont ceux qui faisaient partie d'un sous-menu où autoenablesItems avait été défini sur NO (j'ai confirmé cela dans le xib via l'inspecteur d'attributs pour ce sous-menu et par programme en interrogeant [NSMenu autoenablesItems]. que l'appel à [NSMenuItem setEnabled:] n'a aucun effet car si je demande [NSMenuItem isEnabled] immédiatement après avoir appelé setEnabled: YES, l'état n'a pas changé et il renvoie toujours NO pour isEnabled. Voici un extrait de code avec la sortie il génère:Le paramètre setEnabled de NSMenuItem ne fonctionne pas même si autoenablesItems est défini sur NO pour NSMenu
printf("DEBUG: Current state of menu item is ");
[nsMenuItem isEnabled] ? printf("enabled\n") : printf("DISABLED!\n");
printf("DEBUG: Current state of menu autoenablesItems is ");
[nsMenu autoenablesItems] ? printf("YES\n") : printf("NO\n");
[nsMenuItem setEnabled:YES];
printf("DEBUG: Current state of menu after setting it is ");
[nsMenuItem isEnabled] ? printf("enabled\n") : printf("DISABLED!\n");
sortie:
DEBUG: Current state of menu item is DISABLED!
DEBUG: Current state of menu autoenablesItems is NO
DEBUG: Current state of menu after setting it is DISABLED!
I t également ried sous-classe NSMenuItem et redéfinissant setEnabled pour voir s'il y avait un autre appel à setEnabled qui écrasait mon appel, mais aucun autre appel ne passe par setEnabled.
Si je clique sur le menu parent du sous-menu alors il semble corriger l'état et ces NSMenuItems sont activés, mais il ne passe pas par mon code setEnabled pour changer cet état. J'ai essayé d'ajouter un observateur à la sous-classe activé pour essayer d'attraper où l'état était activé en cliquant sur le menu parent, mais cela ne fournissait aucune information non plus car l'observateur n'était déclenché que pour mes appels à setEnabled ne changent pas réellement l'état. D'après ce que je peux dire en lisant la documentation d'Apple, setEnabled de NSMenuItem devrait fonctionner tant que autoenablesItems est défini sur NO dans le menu parent, mais cela ne semble pas fonctionner dans ce cas, et je ne peux pas comprendre pourquoi.
Dans le même code si j'utilise le SDK 10.7 pour compiler cet appel à setEnabled modifie l'état de NSMenuItem. Quand il entre dans ce code dans la construction 10.7 le NSMenuItem est déjà dans un état activé, mais j'ai essayé de changer l'appel à setEnabled: NO pour confirmer si cela a changé l'état isEnabled, et c'est ce qui a été fait dans la version 10.8 .
Des idées pour lesquelles cela ne fonctionne pas dans 10.8? J'ai aussi essayé avec 10.9 et ça n'a pas marché non plus. J'ai été incapable d'essayer 10.10 ou 10.11 encore puisqu'il y a un autre code qui a besoin d'être mis à jour afin de le compiler avec les plus récents SDK (encore une fois, c'est un vieux code plutôt ancien).
Lorsque ces journaux sont touchés, êtes-vous sûr que nsMenuItem n'est pas en fait nul? Cela entraînerait l'impression de NO pour les deux journaux. Une autre voie d'attaque serait de définir la méthode de validation du menu sur tout objet pertinent (la cible, le premier répondeur) et de voir si (1) il est appelé, et (2) sa valeur de retour est respectée, même lorsque l'auto-habilitation est activée de. Il se passe quelque chose de louche, parce que ce truc est un vieux code et a bien fonctionné dans Cocoa pendant de nombreuses années. Le travail de détective est ce qui est nécessaire. – bhaller
J'ai confirmé que nsMenu et nsMenuItem ne sont pas nuls. J'ai également confirmé qu'après avoir cliqué sur l'élément de menu de niveau supérieur (que nsMenu est un sous-menu de), la prochaine fois que le code est appelé, nsMenu et nsMenuItem sont toujours les mêmes objets (même adresse dans le débogueur) , et que isEnabled retourne alors vrai. La cible sur nsMenuItem est nulle, mais une action est définie. Il a le même état quand cela fonctionne aussi. – user1176103
Lorsque l'équivalent de clé fonctionne, nous nous retrouvons dans le code de l'action définie (via sendEvent de NSApplication suivi de performSelector de NSObject: withObject, suivi de l'action). Lorsque l'équivalent de clé ne fonctionne pas, à partir de sendEvent de NSApplication, nous passons à sendEvent de NSWindow (d'abord via sendEvent de la sous-classe) suivi de _reallySendEvent: isDelayedEvent de NSWindow: suivi de keyDown de la vue. Donc l'action n'est jamais appelée, et je suppose que c'est parce que l'élément de menu est désactivé. – user1176103