【问题标题】:Changing the title of status menu items while the status menu is open is causing crashes in my Cocoa application在状态菜单打开时更改状态菜单项的标题会导致我的 Cocoa 应用程序崩溃
【发布时间】:2010-11-08 21:09:18
【问题描述】:

好的,这个问题变得越来越复杂,所以我将完全从头开始,然后重新开始。我设法创建了一个非常基本的 Cocoa 应用程序来演示我的问题。

那么问题来了:

在线程内部,我在应用程序的状态栏菜单中设置菜单项的标题。 当应用程序尝试更改菜单项的标题并且我打开了菜单时,大多数情况下它可以正常工作,但有时它会使应用程序崩溃。

这里是示例应用的完整代码:

MenubarFailAppDelegate.h

#import <Cocoa/Cocoa.h>

@interface MenubarFailAppDelegate : NSObject <NSApplicationDelegate> {  
    IBOutlet NSMenu *statusMenu;
    NSStatusItem *statusItem;
    IBOutlet NSMenuItem *menuItem;

    int currentDelay;
}

@end

MenubarFailAppDelegate.m

#import "MenubarFailAppDelegate.h"

@implementation MenubarFailAppDelegate

- (id)init {

    self = [super init];

    if (self != nil)
    {
        currentDelay = 0;
    }

    return self;    

}

- (void)awakeFromNib {

    // Create status menu item
    statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength] retain];
    [statusItem setMenu:statusMenu];
    [statusItem setTitle:@"Fail"];
    [statusItem setHighlightMode:YES];

    currentDelay = 3;
    [NSThread detachNewThreadSelector:@selector(changeStatusItemTitleLoopThread)
                             toTarget:self
                           withObject:nil]; 

}

- (void)changeStatusItemTitleLoopThread {

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    while (currentDelay > 0) {
        // Sleep for one second
        NSDate *future = [NSDate dateWithTimeIntervalSinceNow:1];
        [NSThread sleepUntilDate:future];

        // Decrement current delay
        currentDelay--;
    }

    NSLog(@"Setting menu item title");
    [menuItem setTitle:@"lol cat"];

    [pool release];

}

@end

这是在记录“设置菜单项标题”后程序崩溃时出现的崩溃报告:

#0  0x7fff870f74c0 in HIStandardMenuView::FetchItemCache
#1  0x7fff870f6345 in HIStandardMenuView::GetOptimalSizeSelf
#2  0x7fff870f612b in HIView::GetOptimalSizeWithLimitsSelf
#3  0x7fff870f5fb5 in HIView::SendGetOptimalBounds
#4  0x7fff870f5edb in HIView::GetOptimalSize
#5  0x7fff870f5dc1 in HandleCalculateMenuSize
#6  0x7fff8709b600 in MenuData::EventHandler
#7  0x7fff87093997 in DispatchEventToHandlers
#8  0x7fff87092ee6 in SendEventToEventTargetInternal
#9  0x7fff87092d57 in SendEventToEventTargetWithOptions
#10 0x7fff870f5b7a in _CalcMenuSizeOnDevice
#11 0x7fff8710811c in RecalcAndResizeMenu
#12 0x7fff8720efa6 in ResizeMenuArray
#13 0x7fff8720eff6 in ResizeOpenMenus
#14 0x7fff87093997 in DispatchEventToHandlers
#15 0x7fff87092ee6 in SendEventToEventTargetInternal
#16 0x7fff87092d57 in SendEventToEventTargetWithOptions
#17 0x7fff870c012a in ToolboxEventDispatcherHandler
#18 0x7fff87093d91 in DispatchEventToHandlers
#19 0x7fff87092ee6 in SendEventToEventTargetInternal
#20 0x7fff870b0ba9 in SendEventToEventTarget
#21 0x7fff870bdeed in AcquireEventFromQueue
#22 0x7fff870ba737 in ReceiveNextEventCommon
#23 0x7fff87104db8 in IsUserStillTracking
#24 0x7fff870f1a48 in TrackMenuCommon
#25 0x7fff87215ac9 in PopUpMenuSelectCore
#26 0x7fff87215dce in _HandlePopUpMenuSelection7
#27 0x7fff864d71c9 in _NSSLMPopUpCarbonMenu3
#28 0x7fff86706e71 in -[NSStatusBarButtonCell trackMouse:inRect:ofView:untilMouseUp:]
#29 0x7fff8640a4b5 in -[NSControl mouseDown:]
#30 0x7fff86324763 in -[NSWindow sendEvent:]
#31 0x7fff86707c10 in -[NSStatusBarWindow sendEvent:]
#32 0x7fff86259ee2 in -[NSApplication sendEvent:]
#33 0x7fff861f0922 in -[NSApplication run]
#34 0x7fff861e95f8 in NSApplicationMain
#35 0x100001499 in main at main.m:13

【问题讨论】:

  • 请编辑您的问题以包含崩溃报告。另外,rConnectionButton 实际上是 NSButton 吗? (这不会导致崩溃,但会导致混淆,因为出口类型为持有指向 NSMenuItem 的指针,实际上持有指向 NSButton 的指针。)
  • @Peter:我已经编辑了这个问题。为了回答您的问题,rConnectionButton 实际上是 NSMenuItem,而不是 NSButton
  • 是这样吗? #17 之后似乎应该有更多的堆栈帧。
  • @Peter:很抱歉,我错过了他们。我现在已经添加了。
  • 在尝试调整菜单项以使其更大时,它看起来像是崩溃了。这是否提供了有关问题所在的任何提示?

标签: objective-c cocoa crash


【解决方案1】:

通常不建议在线程代码中更改 UI。您需要更改线程中的菜单标题是否有令人信服的理由?我建议将实际更改分派回主线程。您可以在后台线程中进行所需的任何计算,并使用 performSelectorOnMainThread 对标题进行实际更改。

【讨论】:

  • 哇,真的吗?我不知道。您的解决方案有效!太感谢了!顺便问一下,有没有官方说一般不建议进行UI更改是线程代码?我只是好奇我是怎么错过的。
  • 我没有在任何我记得的 Apple 文档中看到它,但我在许多博客上看到过它。我看了看,原来在线程编程指南中对这个问题的讨论非常简短。 developer.apple.com/library/mac/documentation/Cocoa/Conceptual/…
  • 我认为在一些介绍性的 AppKit 材料中提到了它。目前无法查看,因为我正在使用 IE6。 :(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-21
  • 2015-10-06
  • 1970-01-01
  • 2016-01-06
相关资源
最近更新 更多