Cocoa處理訊息的方法:Delegate

來源:互聯網
上載者:User

我們上次示範的程式在關掉了應用程式的視窗之後,應用程式並沒有真正的退出,現在我們就來完成這個任務。

在Mac,Windows或者 Linux平台上,所有的GUI程式都可以稱作訊息驅動的,就是說整個應用程式就是在處理訊息的迴圈中進行的,使用者的操作或者系統發送的一些通知都會被送 到應用程式的訊息處理迴圈中,比如使用者通過鍵盤輸入,用滑鼠點擊視窗等等,有些訊息會直接派發給應用程式的對象,比如滑鼠按下(MouseDown)的消 息就會直接被送給滑鼠按下的那個視窗或者試圖,但是有些訊息會被系統首先解釋,然後在產生其他的訊息,比如使用者用按一下滑鼠視窗Frame上的關閉按鈕,這 個時候MouseDown事件並沒有被送給應用程式的內部對象,而是在應用程式的訊息迴圈中被解釋成了視窗將要關閉的訊息。

我們這次要處理的這個訊息就是 應用程式最後一個視窗關閉的時候, 通知應用程式退出。

Cocoa中處理事件的方式有幾種,其中一種是你可以重載類中的對應的事件處理方 法,比如MouseDown事件在NSResponse類中就被方法mouseDown:處理,所以所有繼承自NSResponse的類都可以重載 mouseDown:方法來實現對MouseDown事件的處理。另外一種處理方式就是使用Delegate,當一個對象接受到某個事件或者通知的時候, 會向它的Delegate物件查詢它是否能夠響應這個事件或者通知,如果可以這個對象就會給它的Delegate對象發送一個訊息(執行一個方法調用), 在代碼中一般用如下的方式來實現。

if (delegate != nil && [delegate respondsToSelector:@selector(theEvent)])
{
    [delegate theEvent];
}

所以如果我們想處理一個對象的事件的話,就可以實現它所要求的方法,然後將實現了這個方法的類的執行個體作為Delegate對象賦值給發出事件的對象。

下面我們就用代碼來說明。
#import <Cocoa/Cocoa.h>
@interface MyDelegate : NSObject {

}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication;
- (BOOL)windowShouldClose:(id)window;
@end

@implementation MyDelegate
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
{
    return YES;
}

- (BOOL)windowShouldClose:(id)window
{
    NSAlert* alert = [[NSAlert alloc] init];
    [alert setAlertStyle:NSInformationalAlertStyle];
    [alert setMessageText:@"Are you sure you want to quit?"];
    [alert addButtonWithTitle:@"Yes"];
    [alert addButtonWithTitle:@"No"];
    NSInteger result = [alert runModal];
    if (result == NSAlertFirstButtonReturn)
    {
        [alert release];
        return YES;
    }
    [alert release];
    return NO;   
}
@end

int main(int argc, char *argv[])
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    [NSApplication sharedApplication];

    //Create the main window
    NSRect rc = NSMakeRect(0, 0, 800, 600);
    NSUInteger uiStyle = NSTitledWindowMask | NSResizableWindowMask | NSClosableWindowMask;
    NSBackingStoreType backingStoreStyle = NSBackingStoreBuffered;
    NSWindow* win = [[NSWindow alloc] initWithContentRect:rc styleMask:uiStyle backing:backingStoreStyle defer:NO];
    [win setTitle:@"HelloWin Test"];
    [win center]; //Center main Window
    [win makeKeyAndOrderFront:win];
    [win makeMainWindow];
   
    //Set delegate to application object
    MyDelegate* myDelegate = [[MyDelegate alloc] init];
    //Use the same delegate object to window object
    [win setDelegate:myDelegate];
    [NSApp setDelegate:myDelegate];
    //Start the event loop by calling NSApp run
    [NSApp run];
    //Release the object
    [myDelegate release];
    [pool drain];
    return 0;
}

首 先定義了一個類名字叫MyDelegate,然后里面實現了兩個方法,這兩個方法是分別對應NSApplication的一個訊息和NSWindow的一 個訊息,我們在實現Delegate對象的時候, 不比針對每個類的Delegate對象單獨建立一個類,比如建立一個MyAppDelegate類,建立一個MyWindowDelegate對象,我們 也不需要將發出事件對象的所有的Delegate方法都實現,只選擇我們需要的就可以了。 所以針對這個簡單的應用程式, 我定義了一個Delegate對象,並且響應了2個對象的兩個事件。

這個Delegate類處理的針對NSApplication的事件是
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
這 個事件是在應用程式的最後一個視窗被關閉之後發出的,NSApplication中有一個視窗的列表,當最後一個視窗關掉的時候, 應用程式就會查詢它的Delegate對象是否響應這個事件,如果響應這個事件,就調用這個方法,然後查看這個方法的傳回值來決定是否退出應用程式。

在這個Delegate類中,這個事件的響應很簡單,直接返回YES,告訴應用程式可以退出了,當然在具體的程式中,我們可以在這個事件中處理一些其他的工作,比如儲存應用的設定或者釋放一些全域的資源等等。

針對NSWindow的事件是
-(BOOL)windowShouldClose:(id)window;
這個事件是在一個視窗將要關掉的時候發出的,我們可以在這個事件中來防止錯誤的操作關掉了進行中的工作,所以可以給使用者彈出一個對話方塊,來確認是否真的要關閉這個視窗。

在 這個事件的處理中,我使用NSAlert類來完成這個簡單的對話方塊,這示範了NSAlert類的強大功能,可以通過這個類來實現更多的這類對話方塊。另外有 些常用的對話方塊,比如Critical Error, Information對話方塊等,Cocoa中已經進行了封裝,我們可以直接調用這些方法, 這樣可以用更少的代碼來完成這個工作。 比如NSRunAlertPanel, NSRunInformationalAlertPanel等等。

雖然我們的程式現在能夠退出了, 但是視窗上面什麼也沒有, 實際上還是一個沒有用的程式,如何來向視窗中增加內容呢?下次在說吧。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.