每個iPhone應用程序都有一個UIApplication,,UIApplication是iPhone應用程序的開始并且負責初始化并顯示UIWindow,,并負責加載應用程序的第一個UIView到UIWindow窗體中,。UIApplication的另一個任務是幫助管理應用程序的生命周期,,而UIApplication通過一個名字為UIApplicationDelegate的代理類來履行這個任務,。盡管UIApplication會負責接收事件,,而UIApplicationDelegate則決定應用程序如何去響應這些事件,UIApplicationDelegate可以處理的事件包括應用程序的生命周期事件(比如程序啟動和關閉),、系統(tǒng)事件(比如來電,、記事項警告),本文會介紹如何加載應用程序的UIView到UIWindow以及如何利用UIApplicationDelegate處理系統(tǒng)事件,。
通常對于UIApplication讀者是沒必要修改它的,,只需要知道UIApplication接收系統(tǒng)事件即可,,而如何編寫代碼來處理這些系統(tǒng)事件則是程序員的工作。處理系統(tǒng)事件需要編寫一個繼承自UIApplicationDelegate接口的類,,而UIApplicationDelegate接口提供生命周期函數(shù)來處理應用程序以及應用程序的系統(tǒng)事件,,這些生命周期函數(shù)如下表所示:
UIApplicationDelegate Event-Handling Methods |
Method Signature |
1:application:didChangeStatusBarFrame: |
- (void)application:(UIApplication*)application didChangeSetStatusBarFrame:(CGRect)oldStatusBarFrame |
2:application:didChangeStatusBarOrientation: |
- (void)application:(UIApplication*)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation |
3:application:handleOpenURL: |
- (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url |
4:application:willChangeStatusBarOrientation:duration: |
- (void)application:(UIApplication*)application willChangeStatusBarOrientation:
(UIInterfaceOrientation)newStatusBarOrientation |
5:application:willChangeStatusBarFrame |
- (void)application:(UIApplication)application willChangeStatusBarFrame:(CGRect)newStatusBarFrame |
6:applicationDidBecomeActive: |
- (void)applicationDidBecomeActive:(UIApplication*)application |
7:applicationDidFinishLaunching: |
- (void)applicationDidFinishLaunching:(UIApplication*)application |
8:applicationDidReceiveMemoryWarning: |
- (void)applicationDidReceiveMemoryWarning:(UIApplication*)application |
9:applicationSignificantTimeChange: |
- (void)applicationSignificantTimeChange:(UIApplication*)application |
10:applicationWillResignActive: |
- (void)applicationWillResignActive:(UIApplication*)application |
11:applicationWillTerminate: |
- (void)applicationWillTerminate:(UIApplication*)application |
表1
如果利用Xcode的模板創(chuàng)建項目,Xcode會為程序員創(chuàng)建繼承自UIApplicationDelegate的類,,但不會自動實現(xiàn)繼承自UIApplicationDelegate的可選的事件處理函數(shù),。如果讀者創(chuàng)建一個名為“TestUIApplication”的項目,Xcode會自動創(chuàng)建TestUIApplicationAppDelegate.h和TestUIApplicationAppDelegate.m文件,,文件的聲明如下:
@interface TestUIApplicationAppDelegate : NSObject 《UIApplicationDelegate》
而應用程序的UIApplication則被定義在MainWindow.xib文件中,,并且有一個作為outlet的UIApplicationDelegate引用,如下圖:
圖1
當應用程序接收到表1中的事件時,,UIApplication會調用UIApplicationDelegate中實現(xiàn)的相應的方法,。
從根本上講,委托(delegate)是iPhone中廣泛采用的一種編程方法,,這種方法有很多益處:
它更為簡潔的把程序的邏輯處理從UIApplication中分離了出來,。
它避免了程序員直接從UIApplication派生子類,試想如果通過從UIApplication派生子類的方法來管理應用程序的生命周期和系統(tǒng)事件是多么痛苦的一件事情,。
每個iPhone應用程序都有一個UIApplication,,UIApplication是iPhone應用程序的開始并且負責初始化并顯示UIWindow,并負責加載應用程序的第一個UIView到UIWindow窗體中,。UIApplication的另一個任務是幫助管理應用程序的生命周期,,而UIApplication通過一個名字為UIApplicationDelegate的代理類來履行這個任務。盡管UIApplication會負責接收事件,,而UIApplicationDelegate則決定應用程序如何去響應這些事件,,UIApplicationDelegate可以處理的事件包括應用程序的生命周期事件(比如程序啟動和關閉)、系統(tǒng)事件(比如來電,、記事項警告),,本文會介紹如何加載應用程序的UIView到UIWindow以及如何利用UIApplicationDelegate處理系統(tǒng)事件。
通常對于UIApplication讀者是沒必要修改它的,,只需要知道UIApplication接收系統(tǒng)事件即可,,而如何編寫代碼來處理這些系統(tǒng)事件則是程序員的工作。處理系統(tǒng)事件需要編寫一個繼承自UIApplicationDelegate接口的類,,而UIApplicationDelegate接口提供生命周期函數(shù)來處理應用程序以及應用程序的系統(tǒng)事件,,這些生命周期函數(shù)如下表所示:
UIApplicationDelegate Event-Handling Methods |
Method Signature |
1:application:didChangeStatusBarFrame: |
- (void)application:(UIApplication*)application didChangeSetStatusBarFrame:(CGRect)oldStatusBarFrame |
2:application:didChangeStatusBarOrientation: |
- (void)application:(UIApplication*)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation |
3:application:handleOpenURL: |
- (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url |
4:application:willChangeStatusBarOrientation:duration: |
- (void)application:(UIApplication*)application willChangeStatusBarOrientation:
(UIInterfaceOrientation)newStatusBarOrientation |
5:application:willChangeStatusBarFrame |
- (void)application:(UIApplication)application willChangeStatusBarFrame:(CGRect)newStatusBarFrame |
6:applicationDidBecomeActive: |
- (void)applicationDidBecomeActive:(UIApplication*)application |
7:applicationDidFinishLaunching: |
- (void)applicationDidFinishLaunching:(UIApplication*)application |
8:applicationDidReceiveMemoryWarning: |
- (void)applicationDidReceiveMemoryWarning:(UIApplication*)application |
9:applicationSignificantTimeChange: |
- (void)applicationSignificantTimeChange:(UIApplication*)application |
10:applicationWillResignActive: |
- (void)applicationWillResignActive:(UIApplication*)application |
11:applicationWillTerminate: |
- (void)applicationWillTerminate:(UIApplication*)application |
表1
如果利用Xcode的模板創(chuàng)建項目,Xcode會為程序員創(chuàng)建繼承自UIApplicationDelegate的類,,但不會自動實現(xiàn)繼承自UIApplicationDelegate的可選的事件處理函數(shù),。如果讀者創(chuàng)建一個名為“TestUIApplication”的項目,Xcode會自動創(chuàng)建TestUIApplicationAppDelegate.h和TestUIApplicationAppDelegate.m文件,,文件的聲明如下:
@interface TestUIApplicationAppDelegate : NSObject 《UIApplicationDelegate》
而應用程序的UIApplication則被定義在MainWindow.xib文件中,,并且有一個作為outlet的UIApplicationDelegate引用,,如下圖:
圖1
當應用程序接收到表1中的事件時,UIApplication會調用UIApplicationDelegate中實現(xiàn)的相應的方法,。
從根本上講,,委托(delegate)是iPhone中廣泛采用的一種編程方法,這種方法有很多益處:
它更為簡潔的把程序的邏輯處理從UIApplication中分離了出來,。
它避免了程序員直接從UIApplication派生子類,,試想如果通過從UIApplication派生子類的方法來管理應用程序的生命周期和系統(tǒng)事件是多么痛苦的一件事情。
同樣,,“委托模式”也是一種常用的面向對象的設計模式,,這種設計模式用Java語言可以更好的進行描述。
“委托模式”中一般有兩個對象參與處理同一個請求,,所謂的請求在iPhone中就是應用程序的生命周期和系統(tǒng)事件,,接受請求的對象將請求委托給另一個對象來處理,同樣在iPhone中對應的是UIApplication在接收到生命周期和系統(tǒng)事件后委托給UIApplicationDelegate來處理,。同樣,,委托模式也是很多其它模式的基礎,如狀態(tài)模式,、策略模式、訪問者模式本質上是在特殊的情況下采用了委托模式,。委托模式使得可以用聚合代理繼承,,正如iPhone中為了避免直接從UIApplication繼承而采用委托模式一樣。
如果用Java來模擬iPhone中委托模式的處理過程,,UIApplication定義大致如下:
public class UIApplication {
public final int UP = 1;
public final int DOWN = 2;
public final int DRAG = 3;
public final int DROP = 4;
private UIApplicationDelegate Delegate;
/**
* @param args
*/
public UIApplication(UIApplicationDelegate aDelegate)
{}
public boolean HandlerSysEvents(int aEventValue)
{
switch(aEventValue)
{
case UP:
Delegate.HanlderEvents(aEventValue);
break;
case DOWN:
Delegate.HanlderEvents(aEventValue);
break;
case DRAG:
Delegate.HanlderEvents(aEventValue);
break;
case DROP:
Delegate.HanlderEvents(aEventValue);
break;
}
return false;
}
}
而委托接口UIApplicationDelegate的定義如下:
public interface UIApplicationDelegate {
public void applicationDidFinishLaunching(UIApplication application);
public boolean HanlderEvents(int aEventsValue);
}
可見,,通過傳遞UIApplicationDelegate到UIApplication中,系統(tǒng)就可以在UIApplication接收到系統(tǒng)事件時調用委托類UIApplicationDelegate中相應的方法來處理系統(tǒng)事件,。
探究iPhone不采用繼承體系而采用委托模式來實現(xiàn)聚合的原因,,其更深層次在于iPhone框架的多樣化使得繼承無法保證子類行為的一致性,而委托模式恰恰是為了彌補繼承的這個缺點誕生的,。
打開Other Sources目錄下main.m文件,,可以看到如下代碼:
#import 《UIKit/UIKit.h》
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc,, argv,, nil, nil);
?。踦ool release];
return retVal;
}
每個項目都會有一個UIApplication對象來處理應用程序的生命周期和系統(tǒng)事件,,main()函數(shù)通過UIApplicationMain()來初始化應用程序的UIApplication,如果讀者想對應用程序的UIApplication進行操作,,就只能通過[UIApplication sharedApplication]來獲取到UIApplication的引用,,這個方法會返回一個全局唯一的UIApplication對象給讀者,。
同樣,讀者可以通過如下代碼獲取應用程序的委托對象:
UIApplicationDelegate* myDelegate = [[UIApplication sharedApplication] delegate];
在UIApplication接收到系統(tǒng)事件和生命周期事件時,,會把相應的事件傳遞給UIApplicationDelegate進行處理,,表1所列的生命周期函數(shù)大都是可選的,但為了應用程序的健壯性程序員應該實現(xiàn)它們,。
iPhone并不是多任務的操作系統(tǒng),,所以應用程序很容易受到打擾,比如一個來電可能導致應用程序失去焦點,,如果這個時候接聽了電話,,那么應用程序會自動終止運行。還有很多其它類似的事件會導致iPhone應用程序失去焦點,,在應用程序失去焦點前會調用委托類的applicationWillResignActive()方法,,而應用程序再次獲取到焦點的時候會調用applicationDidBecomeActive()方法。比如在運行應用程序的時候鎖屏會調用委托類的applicationWillResignActive()方法,,而當屏幕被解鎖的時候,,又會調用applicationDidBecomeActive()方法。
另外一個非常重要的方法就是applicationDidReceiveMemoryWarning(),,因為iPhone設備只有有限的內存,,如果為應用程序分配了太多內存操作系統(tǒng)會終止應用程序的運行,但在終止之前操作系統(tǒng)會通過先調用委托類的applicationDidReceiveMemoryWarning()方法警告應用程序,,在UIApplication接收到這個事件后它會傳遞給委托類的applicationDidReceiveMemoryWarning()方法,,委托類在這個方法內可以進行釋放內存的操作以防止操作系統(tǒng)強制終止應用程序的運行。