2011 Archives
UsingBlocksAsContextInfo - Demonstrates how to implement Objective-C "blocks" passed in as the 'contextInfo' to NSAlert, helping to handle the alert result.
// This is a quick tip on how to use the context info as a block parameter.
// You can use this type of pattern for any methods that have a delegate/selector/contextInfo pattern.
- (void)btnShowAlertClicked:(id)sender {
NSAlert *alert = [NSAlert alertWithMessageText:@"Alert Message"
defaultButton:@"Default Button"
alternateButton:@"Alternate Button"
otherButton:@"Other Button"
informativeTextWithFormat:@"Informative Text"];
BOOL someLocalVariable = YES;
// We create a block that can easily access local variables to this method.
// This is much easier than trying to package them all up into a contextInfo object
void (^blockCallback)(NSInteger) = ^(NSInteger returnCode) {
// Inside the block callback we can easily access locals
if (someLocalVariable) {
if (returnCode == NSAlertDefaultReturn) {
[button setTitle:@"Default Return Button Clicked!"];
} else {
[button setTitle:@"Something else clicked...try again."];
}
}
};
// We copy the block, since it needs to stay alive for longer than the current scope
[alert beginSheetModalForWindow:self.window
modalDelegate:[self class]
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
contextInfo:Block_copy(blockCallback)];
}
+ (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void (^)(NSInteger returnCode))continuationHandler {
continuationHandler(returnCode);
// The block must always be retained before the first call. This is the matching release
Block_release(continuationHandler);
}
static void _processData(AppDelegate *self, NSInteger i) {
// Notice that the _window can be accessed here, even though it is a private ivar
// A compiler error (or warning) will happen if this method was outside the @implementation scope of AppDelegate.
NSLog(@"Processing %d in window %@", i, self->_window);
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
for (NSInteger i = 0; i < 200; i++) {
_processData(self, i);
}
}
#import <Cocoa/Cocoa.h> |
int main(int argc, char *argv[]) |
{ |
return NSApplicationMain(argc, (const char **) argv); |
} |
NSMainNibFile,并load之程序启动完成
程序状态管理和维护通过
NSApplication,NSApplicationDelegateNSNibLoading,单独load
使用NSBundle 3个方法
+ (BOOL)loadNibFile:(NSString *)fileName externalNameTable:(NSDictionary *)context withZone:(NSZone *)zone;
+ (BOOL)loadNibNamed:(NSString *)nibName owner:(id)owner;
- (BOOL)loadNibFile:(NSString *)fileName externalNameTable:(NSDictionary *)context withZone:(NSZone *)zone;
看起来第二个更简单些
另外Document base Application NSDocument 类可以使用
- (NSString *)windowNibName;方法加载目标Nib文件
NSWindowController 同样可以使用上面的这个方法

NSApplicationDelegate
实现
- (NSMenu *)applicationDockMenu:(NSApplication *)sender
{
return _menu;
}
2 状态条菜单
需要NSMenuDelegate protocol
@protocol NSMenuDelegate <NSObject>
@optional
- (void)menuNeedsUpdate:(NSMenu*)menu;
- (NSInteger)numberOfItemsInMenu:(NSMenu*)menu;
- (BOOL)menu:(NSMenu*)menu updateItem:(NSMenuItem*)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel;
- (void)menuWillOpen:(NSMenu *)menu;
- (void)menuDidClose:(NSMenu *)menu;
- (void)menu:(NSMenu *)menu willHighlightItem:(NSMenuItem *)item;
@end

给StatusBar加Icon
- (void)activateStatusMenu:(int)status
{
NSStatusBar *bar = [NSStatusBar systemStatusBar];
icon = [bar statusItemWithLength:NSVariableStatusItemLength];
[icon retain];
NSString* filePath;
switch (status) {
case 0:
filePath = [[NSBundle mainBundle] pathForResource:@"sync_complete" ofType:@"png"];
break;
case 1:
filePath = [[NSBundle mainBundle] pathForResource:@"sync_processing" ofType:@"png"];
break;
case 2:
filePath = [[NSBundle mainBundle] pathForResource:@"sync_error" ofType:@"png"];
break;
default:
break;
}
NSImage* image = [[NSImage alloc] initWithContentsOfFile:filePath];
[icon setImage:image];
[icon setHighlightMode:YES];
[icon setMenu:mainMenu];
}
关于菜单就讲这么多
NSWindowController
- (id)initWithWindow:(NSWindow *)window
或者使用 - (NSString *)windowNibName
NSWindowController *controller = [[c alloc] init];
if (_windowControllers == nil) {
_windowControllers = [NSMutableArray new];
}
[_windowControllers addObject:controller];
[controller showWindow:self];//显示Window,self 为NSWindowController
[controller release];
注册窗口关闭通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowClosed:) name:NSWindowWillCloseNotification object:nil];
处理关闭窗口通知,移出不需要的Window
- (void)_windowClosed:(NSNotification *)note {
NSWindow *window = [note object];
for (NSWindowController *winController in _windowControllers) {
if (winController.window == window) {
[[winController retain] autorelease]; // Keeps the instance alive a little longer so things can unbind from it
[_windowControllers removeObject:winController];
break;
}
}
}


