【问题标题】:Menu of app in Status Bar wont work on Snow Leopard状态栏中的应用程序菜单在 Snow Leopard 上不起作用
【发布时间】:2009-11-04 18:06:24
【问题描述】:

我有一个位于 Mac 状态栏中的应用程序。它有一个菜单,可让您查看应用版本、更改一些设置并退出应用。

我在 Leopard 上构建了它,它在 Leopard 上运行良好。 在 Snow Leopard 上,我可以在状态栏中看到该应用程序,单击它会显示菜单项。但是单击菜单中的项目不会执行任何操作。该应用程序没有挂起 - 它正在做预期做的事情。 UI 线程也没有挂起 - 我可以清楚地看到菜单,并且应用程序导致在 UI 线程上显示的对话框(在单击菜单时显示的对话框除外)显示得很好。在面向 10.6 的 Snow Leopard 上编译它似乎并没有改变这种行为。

所以我知道该应用程序能够创建对话框,没有挂起并且正在运行。 我怀疑这与菜单有关,并且在我的应用程序或 Snow Leopard 中处理菜单点击。

还有其他人对这可能是什么或我应该看哪里有建议吗?关于我可以在哪里放置 BP 以捕获菜单项单击是否实际发生的任何建议?

编辑:我上传了一个简单的 repro 10.6 XCode 项目。如果您可以看一下,我会按您的方式发送虚拟啤酒,如果您发现有什么问题,请告诉我。该应用程序很简单 - 创建一个带有 1 个菜单项“退出”的状态栏应用程序,该菜单项在应用程序上调用终止。状态栏应用程序显示,菜单显示,但单击什么也不做。 Here's the project。它在 Leopard 上运行良好(在构建/运行之前清理所有内容),但在 Snow Leopard 上却不行。

【问题讨论】:

    标签: macos osx-snow-leopard


    【解决方案1】:

    听起来您的菜单项的操作出口可能没有“连接”到您代码中的任何内容。从您的描述中我不知道您是在界面生成器中创建菜单还是以编程方式创建菜单,但首先要做的是在那里检查。确保如果您以编程方式创建菜单,并且在 @selector() 中正确拼写了方法名称(如果您收到警告说“[class] may not respond to -Foo”,那就太严重了提示错字)。

    如果连接看起来不错,我会断点设置为您的操作的方法,并验证您实际上调用的是您认为的方法。

    如果您以编程方式设置连接,请对 addItemWithTitle:(或等效调用)调用进行断点,并确保您的 NSMenuItem 在跨过该行后立即正确设置。

    ---编辑---

    查看发布的代码后,它存在几个根本缺陷,其中任何一个都可能导致 10.6 下的损坏。

    1. 首先,您混淆了代表与菜单相关的角色。委托不应是您的 NSMenu 对象,您的委托应该是由 NSMenuItem 作为“回调”调用以提供自定义逻辑的对象。你根本不需要扩展 NSMenu,你的 MenuTestAppDelegate 应该只从 NSObject 扩展。

    2. MainMenu.xib 文件中 Menu 对象的类是 MenuTest 类型,但您的项目中没有声明 MenuTest 类。希望这只是您在设置测试项目时出现的复制/粘贴错误,但您应该检查一下。

    3. 我发现以编程方式设置 NSStatusItem 的菜单要容易得多。试试这个:


    // create the menu
    - (void)createMenu
    {   
        NSMenu* aMenu = [NSMenu new];
        [aMenu setDelegate:self];
    
        NSMenuItem* quitItem = [[NSMenuItem alloc] initWithTitle:@"quitItem"
                               action:@selector(quitSelected:) 
                               keyEquivalent:@""];
    
        [aMenu addItem:quitItem];
        [quitItem release];
    
        NSStatusItem* statusItem = [[NSStatusBar systemStatusBar]
                                   statusItemWithLength:NSVariableStatusItemLength];
    
        NSImage* itemImage = [[NSImage alloc] initWithContentsOfFile:
                             [[NSBundle mainBundle] pathForResource:@"image" ofType:@"png"]];
        NSImage* itemAlternate = [[NSImage alloc] initWithContentsOfFile:
                                 [[NSBundle mainBundle] pathForResource:@"alternate" ofType:@"png"]];
    
        [statusItem setImage:itemImage];
        [statusItem setAlternateImage:itemAlternate];
    
        [statusItem setHighlightMode:YES];
        [statusItem setMenu:aMenu];
    }
    

    【讨论】:

    • 谢谢。我不是以编程方式添加这些菜单项。我在 IB 中创建了菜单。这些没有连接听起来很合理,除了它们是 - Leopard 上的相同二进制函数。有没有什么场景你知道从 10.5->10.6 发生了什么变化?
    • @psychotik 不幸的是,对于 10.5 -> 10.6 破坏接口的情况,没有什么特别的。只是做一个最好的猜测......
    • 我上传了一个简单的复制品 - 如果你有时间,我会很感激你看看,以防你能弄明白。大约 20 行代码 + xib。
    • 彼得,感谢您的收看。 #1 不是标准的,但菜单项 is 是一个对象,所以应该没问题,特别是因为 10.5 没有问题。我会尝试使用更标准的方式,如果有帮助,请告诉您。 #2 只是类名与文件名不匹配的情况。否则它不会在 10.5 上运行。 #3 是一种有趣的方法——当然看起来很有希望。我会试一试这些变化。谢谢!
    • 切换到使用动态菜单并且在设计器中没有菜单的委托似乎已经成功了。我正在查看一些关于 10.6 中菜单新功能的文档,我发现这个新协议可能与它有关 - 基本上,您设置为委托的对象需要实现这个接口,我相信 - 它只是 10.6。 developer.apple.com/mac/library/documentation/Cocoa/Reference/…
    猜你喜欢
    • 2016-01-16
    • 1970-01-01
    • 2019-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多