首页 文章

NSMenuDelegate未在另一个NSMenuDelegate创建的NSMenuItem中调用子菜单

提问于
浏览
3

我有一个带有委托的NSMenu的NSStatusItem . 该委托根据几个因素动态更新菜单 . 所以根据文档,为了快速更新菜单,我使用的方法:

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

在此方法的适当时候,我调用以下内容:

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

状态菜单显示正确,相应的菜单项具有子菜单的显示三角形;但是,当相应项目突出显示时,子菜单不会出现,即使在SomeSubmenuDelegate中存在以下方法,根据我的经验,应显示三个空白菜单项:

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

记录也没有做任何事情,即使在menuWillOpen中也没有,所以看起来方法永远不会被调用,让我相信委托是未设置的某个地方,或者在运行时以某种方式复制菜单并且代理在流程中未设置...

现在的解决方法是在顶级NSMenuDelegate(对于NSStatusItem的菜单)中创建整个子菜单,而不是分配委托 . 这里有一些缺点

1)我在NSMenuDelegate中保持我的行为,并且为父和子菜单提供单独的文件会很好 .

2)虽然不一定是重要的,但这意味着我在每个需要之前为每个子菜单NSMenuItem分配内存 .

这似乎是最佳的,我应该能够在这里使用委托,就像任何其他NSMenu一样 .

任何想法/建议都非常感谢 . 这里的第一个问题!

编辑:这是因为ARC吗?我可能错误地认为,根据惯例,ARC会保留委托对象,考虑垃圾收集,但也许它正在被释放,因为委托是弱引用而ARC不会做出类似的假设 . 我只能在Apple文档中找到对垃圾收集的引用,这确实说垃圾收集会保持强大的引用......但很明显,ARC不是垃圾收集,我找不到任何关于此的信息 . 这意味着我需要在父委托中保留委托,这对于如此动态的东西来说似乎很难看 . 有没有办法在ARC下保留委托,然后在适当的时候释放它而不在父委托(或其他任何地方)的引用?

1 回答

  • 0

    在我的例子中,我将菜单实例的声明从方法移动到成员变量 .

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

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

    方法:'createMenuStructure'在本地创建我的菜单 . 'MyMenu'实现了NSMenuDelegate .

    这将myMenu变量保存为强引用 . 处理程序现在完美运行 .

相关问题