2012-01-15 3 views
9

何ヶ月も何も作業していない状態で、Cocoa開発に取り掛かり始めました。もともと私が始めたとき、私はSnow LeopardとXcode 3を使用していました。私はXcode 4.2でLionを実行しています。以前は実行していなかったいくつかの問題が発生しています。NSStatusItemは起動時に一時的に表示されますが、ただちに表示されなくなります

以前はARCを使用したことがないと思われるので、私は何か不足していると確信しています。

メインウィンドウやドックアイコンなしでステータスバーアプリケーションを作成しようとしています。アプリケーションを実行すると、アプリケーションのステータスバーアイコンが約1秒間表示されますが、表示されなくなります。

Heres my code。

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

コードのご提案:現在の画像読み込みコードの代わりに[appBundle imageForResource:@ "statusItemIcon"]を使用してください。より速く、@ 2xイメージを透過的にサポートし、コード変更なしで非pngをサポートし、読みやすくなります。 –

+0

@Catfish_Manありがとう!それはまさに私が探している種類の批判です! –

答えて

16

この場合、_statusItemは自動リリースされます。

_statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength]; 

これは、自動リリースされたオブジェクトを返します。 _statusItemはちょうどiVarです。それだけでなく、あなたが割り当てとしてプロパティを宣言:

@property (assign) NSStatusItem *statusItem; 

あなたはおそらく、ここで何をしたいプロパティstrongを行い、その後、代わりに直接IVARを設定するのは、それを設定するプロパティを使用しています。

@property (strong) NSStatusItem *statusItem; 

、その後:

self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength]; 

statusItemが保持する原因になりますように、このような。私は、今起こっていることは、自動解放プールがポップしたときに解放され、次に何かがアクセスしようとしたときにアプリケーションがクラッシュして、メニューバーから消えてしまうことだと賭けている。ゾンビの音源を使ってそれを実行すると、それが起こっていたのかどうかを確かめることができます。しかし、一般的に、あなたのアプリはそのオブジェクトを強く参照する必要があります。

+0

ありがとうございます。私はプロパティを強く変更し、それは素晴らしい作品です。それが意図された通りに働いているにもかかわらず、私はまだiVarを削除し、直接プロパティで作業する必要がありますか?そのようにすることのメリットは何ですか? –

+1

ivarがプロパティを返します。 @synthesizedプロパティは、サブクラスでオーバーライドできるメモリ管理要件を処理するsetterメソッドとgetterメソッドを生成しました。一般的に、私はsetter/getterメソッドを-initや-dealloc以外の場所で使用していますが、特にパフォーマンス(タイトなループなど)がない特別な理由がある場合を除きます。つまり、ARCは合成されたivarのプロパティ管理宣言からそのメモリ管理動作を推測することができなければならないので、プロパティが「強」と宣言されていると仮定すると、ivarを直接使用する必要があります。 – ipmcc

+1

ARC前の日には、セッター/ゲッターを使用してメモリ管理動作を「無料で」行う必要がありました。 ivarに直接アクセスする場合、同等のメモリ管理動作を手動で提供することが期待されます。私はまだARC以外のコードベースで作業していますので、それが私の最初のコメントの由来です。 – ipmcc

0

私は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; 
    } 

Iに示し続けましたそれを(強く)に変更する必要はありませんでした。実際、私は試しましたが、Xamarin Studioにコピーし直すときにはそれが維持されませんでした。

関連する問題