2012-01-15 32 views
9

Tôi bắt đầu trở lại phát triển Ca cao sau khi không làm việc gì trong vài tháng. Ban đầu khi tôi bắt đầu tôi đã sử dụng Snow Leopard và Xcode 3. Tôi hiện đang chạy Lion với Xcode 4.2 và tôi đang chạy vào một số vấn đề mà tôi đã không chạy vào trước.NSStatusItem xuất hiện một thời gian ngắn khi ra mắt, nhưng nhanh chóng biến mất

Tôi tin rằng có lẽ thực tế là tôi chưa bao giờ sử dụng ARC trước đây, vì vậy tôi chắc chắn tôi đang thiếu thứ gì đó.

Tôi đang cố gắng tạo ứng dụng Statusbar, không có cửa sổ chính hoặc biểu tượng đế. Khi tôi chạy ứng dụng, biểu tượng Statusbar cho ứng dụng của tôi xuất hiện một thời gian ngắn, trong khoảng một giây, nhưng sau đó biến mất.

Heres mã của tôi.

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 

Sửa Nếu bạn thấy bất cứ điều gì sai trái với mã của tôi xin vui lòng cho tôi biết. Tôi chắc chắn sẽ có một số phê bình để tôi có thể trở nên tốt hơn.

Chỉnh sửa khác Dường như biểu tượng thanh trạng thái biến mất khi cửa sổ chính tự tải.

+0

Đề xuất mã của bạn: Sử dụng [appBundle imageForResource: @ "statusItemIcon"] thay vì mã tải hình ảnh hiện tại của bạn. Nó phải nhanh hơn, hỗ trợ hình ảnh @ 2x một cách minh bạch, hỗ trợ không png mà không cần thay đổi mã và dễ đọc hơn :) –

+0

@Catfish_Man Cảm ơn bạn! Đó chính là loại phê bình mà tôi đang tìm kiếm! –

Trả lời

16

_statusItem sẽ được tự động phát hành trong trường hợp này.

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

Điều này trả về đối tượng tự động. _statusItem chỉ là một iVar. Không chỉ có vậy, nhưng bạn khai báo tài sản như assign:

@property (assign) NSStatusItem *statusItem; 

Những gì bạn có thể muốn làm ở đây là làm cho tài sản strong và sau đó, thay vì thiết Ivar trực tiếp, sử dụng tài sản để thiết lập nó. Vì vậy, như thế này:

@property (strong) NSStatusItem *statusItem; 

và sau đó:

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

Điều đó sẽ gây ra statusItem được giữ lại. Tôi cá rằng những gì đang xảy ra bây giờ là nó được phát hành khi nhóm autorelease bật lên, và sau đó ứng dụng của bạn gặp sự cố tiếp theo khi truy cập vào nó, khiến nó biến mất khỏi thanh trình đơn. Chạy nó thông qua các công cụ Zombies sẽ cho bạn biết chắc chắn nếu đó là những gì đã xảy ra. Nhưng nói chung, ứng dụng của bạn cần phải có một tham chiếu mạnh mẽ đến đối tượng đó để nó dính quanh.

+0

Cảm ơn bạn. Tôi đã thay đổi tài sản thành mạnh mẽ và nó hoạt động rất tốt. Với nó làm việc theo cách nó đã được dự định, tôi vẫn nên loại bỏ iVar và làm việc trực tiếp với tài sản? Lợi ích của việc làm theo cách đó là gì? –

+1

Ngà che chắn tài sản. Các thuộc tính @synthesized đã tạo ra các phương thức setter và getter xử lý các yêu cầu quản lý bộ nhớ có thể được ghi đè trong một lớp con. Nói chung, tôi muốn nói sử dụng các phương thức setter/getter ở bất kỳ nơi nào khác ngoài -init và -dealloc, trừ khi có một lý do cụ thể nào đó không (giống như hiệu suất có nghĩa là các vòng chặt). Điều đó nói rằng, ARC có thể suy ra hành vi quản lý bộ nhớ của một bảng tổng hợp từ việc khai báo thuộc tính của nó, vì vậy việc sử dụng trực tiếp ivar cũng có thể hoạt động, giả sử thuộc tính được khai báo là 'strong'. – ipmcc

+1

Trong những ngày trước ARC, bạn sẽ phải sử dụng setter/getters để có được hành vi quản lý bộ nhớ "miễn phí". Khi truy cập trực tiếp vào ivar, bạn sẽ được yêu cầu cung cấp các hành vi quản lý bộ nhớ tương đương một cách thủ công. Tôi vẫn làm việc chủ yếu với các mã không phải ARC, vì vậy đó là nơi nhận xét ban đầu của tôi xuất phát từ đó. – ipmcc

0

Tôi gặp sự cố này ở Xamarin. Trong một thời gian nó hoạt động tốt. Sau đó, tôi đã thêm mã bổ sung vào phương thức FinishedLaunching và StatusItem bắt đầu biến mất. Tôi đã có mã này tạo 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; 
    } 

Cuối cùng, tôi đã tìm thấy sự cố của mình.Trong Xcode của tôi, tôi đã tuyên bố sở hữu trong appdelegate tôi đây nhưng tôi đã không sử dụng nó:

@property(nonatomic, retain) IBOutlet NSStatusItem *statusItem; 

Khi tôi gỡ bỏ var các StatusItem tiếp tục thể hiện trong vinh quang vô hạn của nó :)

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

tôi không phải thay đổi nó thành (mạnh). Trong thực tế tôi đã thử nhưng nó không tồn tại khi sao chép trở lại Xamarin Studio.

Các vấn đề liên quan