1.9 从Terminal中创建一个基于Mac Window的应用
1、问题
虽然在Mac上一般都是用Xcode来开发rich window-based应用。但有时候不利用Xcode项目模板插入到你的代码中的帮助会更容易看到发生了什么。
2、解决方案
Mac apps需要一些关键的组件才能工作。也就是,你需要使用NSApplication和NSWindow类来管理的应用自身以及初始的用户界面。你还需要一个app委托类,是在一个独立的文件中编写的。该app委托扮演着应用的一个帮助者,就是说要在其中编写一些关键的方法,应用工作需要用到这些方法。
3、原理
(1)App委托:
Mac应用使用了一个设计模式:委托。当你想要实现委托时,你就指派一个对象(叫委托)为另一个对象来行使权利。
app委托是一个类,需要它自己的头和实现文件。Mac app委托必须导入Cocoa框架并实现NSApplicationDelegate协议。协议就是一组属性和方法,一个类要担任委托就必须实现这些属性和方法。
定义一个app委托:
@interface AppDelegate : NSObject <NSApplicationDelegate>
app委托应当要有一个NSWindow属性并实现委托方法:(void)applicationDidFinishLaunching:(NSNotification *)aNotification;
NSWindow属性就是UI元素,你就是在它上面放用户内容的。委托方法就是一个通知,它是在你的应用完成启动时执行的。
(2)Application
Mac应用自身和前面一样,是从main函数中建立和启动的。首先需要得到NSApplication的一个实例。NSApplication是一个Cocoa类,它用了单例模式。意味着一个应用只有一个NSApplication实例。你必须用一个特别的过程来得到该对象的一个引用。
NSApplication *macApp = [NSApplication sharedApplication];
sharedApplication是一个class方法,它要么是实例化并返回一个新实例或者是返回之前就创建好过的一个实例。
一旦有了Mac application的一个应用,就能够创建一个app委托并将它设置为macApp的委托。
AppDelegate *appDelegate = [[AppDelegate alloc] init];
macApp.delegate = appDelegate;
然后,你的application必须要有一个window,所以用NSWindow类实例化一个window,将app委托的NSWindow设置为该window。
int style = NSClosableWindowMask | NSResizableWindowMask |
NSTexturedBackgroundWindowMask | NSTitledWindowMask | NSMiniaturizableWindowMask;
NSWindow *appWindow = [[NSWindow alloc] initWithContentRect:NSMakeRect(50, 50, 600, 400)
styleMask:style
backing:NSBackingStoreBuffered
defer:NO];
appDelegate.window = appWindow;
好了,运行就行了
[appWindow makeKeyAndOrderFront:appWindow];
[macApp run];
4、代码
Listing 1-16. AppDelegate.h
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (assign) NSWindow *window;
@end
---------------------------------------------------------------------------------
Listing 1-17. AppDelegate.m
#import "AppDelegate.h"
@implementation AppDelegate
@synthesize window = _window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{
NSLog(@"Mac app finished launching");
}
@end
------------------------------------------------------------------------------------
Listing 1-18. main.m
#import "AppDelegate.h"
int main (int argc, char *argv[]){
NSApplication *macApp = [NSApplication sharedApplication];
AppDelegate *appDelegate = [[AppDelegate alloc] init];
macApp.delegate = appDelegate;
int style = NSClosableWindowMask | NSResizableWindowMask |
NSTexturedBackgroundWindowMask | NSTitledWindowMask |
NSMiniaturizableWindowMask;
NSWindow *appWindow = [[NSWindow alloc] initWithContentRect:NSMakeRect(50, 50, 600, 400)
styleMask:style
backing:NSBackingStoreBuffered
defer:NO];
appDelegate.window = appWindow;
[appWindow makeKeyAndOrderFront:appWindow];
[macApp run];
}
5、调用——注意要链接到Cocoa
clang -fobjc -framework Cocoa AppDelegate.m main.m -o macwindowapp