在几个月没有做任何事情之后,我开始重新回到Cocoa开发阶段。最初我开始使用Snow Leopard和Xcode 3.我现在正在使用Xcode 4.2运行Lion,我遇到了一些我之前没遇到过的问题。
我相信这可能是因为我之前从未使用过ARC,所以我确定我错过了一些东西。
我正在尝试创建状态栏应用程序,没有主窗口或停靠图标。当我运行应用程序时,我的应用程序的状态栏图标会短暂显示,大约一秒钟,然后消失。
继承我的代码。
QuickPlusAppDelegate.h
#import <Cocoa/Cocoa.h>
@interface QuickPlusAppDelegate : NSObject <NSApplicationDelegate>
@property (assign) IBOutlet NSWindow *window;
@property (assign) NSStatusItem *statusItem;
@property (weak) IBOutlet NSMenu *statusItemMenu;
@property (strong) NSImage *statusItemIcon;
@property (strong) NSImage *statusItemIconHighlighted;
@property (strong) NSImage *statusItemIconNewNotification;
@end
QuickPlusAppDelegate.m
#import "QuickPlusAppDelegate.h"
@implementation QuickPlusAppDelegate
@synthesize statusItemMenu = _statusItemMenu;
@synthesize window = _window, statusItem = _statusItem;
@synthesize statusItemIcon = _statusItemIcon,
statusItemIconHighlighted = _statusItemIconHighlighted,
statusItemIconNewNotification = _statusItemIconNewNotification;
- (void) awakeFromNib
{
NSBundle *appBundle = [NSBundle mainBundle];
_statusItemIcon = [[NSImage alloc] initWithContentsOfFile:[appBundle pathForResource:@"statusItemIcon" ofType:@"png"]];
_statusItemIconHighlighted = [[NSImage alloc] initWithContentsOfFile:[appBundle pathForResource:@"statusItemIconHighlighted" ofType:@"png"]];
_statusItemIconNewNotification = [[NSImage alloc] initWithContentsOfFile:[appBundle pathForResource:@"statusItemIconNewNotification" ofType:@"png"]];
_statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
[_statusItem setImage:_statusItemIcon];
[_statusItem setAlternateImage:_statusItemIconHighlighted];
[_statusItem setHighlightMode:YES];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// empty
}
@end
修改如果您发现我的代码有任何问题,请告诉我们。我肯定会批评一些,所以我可以变得更好。
另一个编辑当主窗口本身加载时,状态栏图标似乎消失了。
答案 0 :(得分:19)
_statusItem将自动释放。
_statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
这将返回一个自动释放的对象。 _statusItem只是一个iVar。不仅如此,您还将该属性声明为assign:
@property (assign) NSStatusItem *statusItem;
你可能想要做的是创建属性strong
,然后使用属性来设置它,而不是直接设置ivar。像这样:
@property (strong) NSStatusItem *statusItem;
然后:
self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
这将导致statusItem被保留。我打赌现在发生的事情是当自动释放池弹出时它会被释放,然后你的应用程序在下次有任何尝试访问它时崩溃,从而导致它从菜单栏中消失。通过Zombies仪器运行它会告诉你确定这是不是发生了什么。但一般来说,您的应用需要对该对象有强烈的引用才能保持这种状态。
答案 1 :(得分:1)
我在Xamarin遇到了这个问题。有一段时间它运作良好。然后我向FinishedLaunching
方法添加了额外的代码,StatusItem开始消失。我有这个代码生成StatusItem:
public override void AwakeFromNib ()
{
var statusItem = NSStatusBar.SystemStatusBar.CreateStatusItem (30);
statusItem.Menu = mainMenu;
statusItem.Image = NSImage.ImageNamed ("menuicon");
statusItem.AlternateImage = NSImage.ImageNamed ("menuicon_selected");
statusItem.HighlightMode = true;
}
最终,我发现了我的问题。在我的Xcode中,我在AppDelegate中声明了这个属性,但我没有使用它:
@property(nonatomic, retain) IBOutlet NSStatusItem *statusItem;
当我删除var
时,StatusItem继续显示其无限荣耀:)
public override void AwakeFromNib ()
{
statusItem = NSStatusBar.SystemStatusBar.CreateStatusItem (30);
statusItem.Menu = mainMenu;
statusItem.Image = NSImage.ImageNamed ("menuicon");
statusItem.AlternateImage = NSImage.ImageNamed ("menuicon_selected");
statusItem.HighlightMode = true;
}
我没有必要将其改为(强)。事实上我尝试了但是在复制回Xamarin Studio时它没有坚持。