【问题标题】:Minimal Cocoa application - problem with menu最小的 Cocoa 应用程序 - 菜单问题
【发布时间】:2018-10-03 17:52:56
【问题描述】:

我需要在没有 Xcode 的情况下实现最小的 Cocoa 应用程序。我正在尝试这个例子:

https://www.cocoawithlove.com/2010/09/minimalist-cocoa-programming.html

#import <Cocoa/Cocoa.h>

int main()
{
    [NSAutoreleasePool new];
    [NSApplication sharedApplication];
    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
    id menubar = [[NSMenu new] autorelease];
    id appMenuItem = [[NSMenuItem new] autorelease];
    [menubar addItem:appMenuItem];
    [NSApp setMainMenu:menubar];
    id appMenu = [[NSMenu new] autorelease];
    id appName = [[NSProcessInfo processInfo] processName];
    id quitTitle = [@"Quit " stringByAppendingString:appName];
    id quitMenuItem = [[[NSMenuItem alloc] initWithTitle:quitTitle
        action:@selector(terminate:) keyEquivalent:@"q"] autorelease];
    [appMenu addItem:quitMenuItem];
    [appMenuItem setSubmenu:appMenu];
    id window = [[[NSWindow alloc] initWithContentRect:NSMakeRect(10, 10, 200, 200)
        styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO]
            autorelease];
    [window setTitle:appName];
    [window makeKeyAndOrderFront:nil];
    [NSApp activateIgnoringOtherApps:YES];
    [NSApp run];
    return 0;
}

它运行良好,除了一个小问题:启动后,菜单立即更改,但处于非活动状态(单击它什么也不做)。如果我选择其他一些应用程序,然后返回到那个最小的应用程序,菜单就会按预期开始工作。

知道如何解决这个问题吗?

【问题讨论】:

  • 找到了!看起来二进制文件必须在 Contents/MacOS 文件夹中。如果我将我的二进制文件移动到这样的文件夹中,菜单会按预期开始工作。
  • 这或多或少违背了 CLI 应用程序的目的,因为您现在创建的是一个 .app 包。
  • 对我来说,关键字不是“CLI”而是“minimal”……而且不用 XCode。
  • 我会改写;您不再创建仅包含一个文件的“最小”Cocoa 应用程序。你有一个应用程序包,它要求你的二进制文件被埋在两个目录深处。尽管您最初描述的行为是出乎意料的,并且您不需要创建 .app 包作为解决方法,但您在问题中从未提及任何关于不使用 Xcode 的内容。
  • 实际上,这就是现在“最小”的 Cocoa 应用程序。 Minimal 现在需要创建最小的应用程序包,否则菜单不起作用,因为 Apple 破坏了一些东西。没有人对“一个文件”说任何话:)好吧,这一切都是在吹毛求疵,无论如何我相信我的信息可以帮助完成相同任务的人(相信我,我在谷歌上搜索了 2 天,然后才在这里发布问题)。

标签: objective-c macos cocoa


【解决方案1】:

对于最小的应用程序,我也有同样的问题。他们没有正确处理事件。

此时 (10.15.2 (19C57)) 这些是它正常工作所需要的。

  • 带有.app 扩展名的应用程序包文件夹。 (可能是可选的)
  • Contents/Info.plistCFBundleIdentifier 值。 (不需要其他密钥)
  • Contents/MacOS/(your-executable) 文件。

【讨论】:

    【解决方案2】:

    这似乎是macOS 高于版本 10.8.5 的某个错误。

    我尝试了代码(以及 10.13.6 中的类似变体),但它们都以您描述的方式失败。编译相同的代码并在版本10.8.5上运行没有相同的行为,并且可以正常访问菜单。

    结论

    我建议将此行为报告给 Apple。

    旁注:您需要删除代码中的 autorelease 部分,因为 ARC 禁止这样做,并且不能与最新的 Xcode SDK 一起使用。

    【讨论】:

    • Bug 与否,“常规”macos 应用程序不会出现这种行为。所以那里一定有“缺失的成分”...... WRT autorelease:我的理解是ARC是可选的。这不再是真的了吗?
    • 我唯一能想到的是问题在setActivationPolicy 内,并且没有缺少的成分,因为它应该可以工作,而且在最新版本的操作系统中根本不起作用。关于ARC,是的,它是可选的,但是,如果可能,建议使用它(在您的示例中这很容易)。
    【解决方案3】:

    根据https://github.com/rgl/minimal-cocoa-appNSApplicationActivationPolicyRegularactivateIgnoringOtherApps: 似乎丢失了

    这是更新后的代码:

    // cc -o min-cocoa min-cocoa.m -framework Cocoa
    #import <Cocoa/Cocoa.h>
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            [NSApplication sharedApplication];
            id menubar = [NSMenu new];
            id appMenuItem = [NSMenuItem new];
            [menubar addItem:appMenuItem];
            [NSApp setMainMenu:menubar];
            id appMenu = [NSMenu new];
            id appName = [[NSProcessInfo processInfo] processName];
            id quitTitle = [@"Quit " stringByAppendingString:appName];
            id quitMenuItem = [[NSMenuItem alloc] initWithTitle:quitTitle action:@selector(terminate:) keyEquivalent:@"q"] ;
            [appMenu addItem:quitMenuItem];
            [appMenuItem setSubmenu:appMenu];
            id window = [[NSWindow alloc] initWithContentRect:NSMakeRect(10, 10, 200, 200) styleMask:NSWindowStyleMaskTitled backing:NSBackingStoreBuffered defer:NO];
            [window setTitle:appName];
            [window cascadeTopLeftFromPoint:NSMakePoint(20,20)];
            [window makeKeyAndOrderFront:nil];
    
            [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
    
            dispatch_async(dispatch_get_main_queue(), ^{
                [NSApp activateIgnoringOtherApps:YES];
            });
    
            [NSApp run];
        }
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-12
      • 1970-01-01
      相关资源
      最近更新 更多