對於iOS開發,舉例Cocoa框架下的幾個設計模式爲你們分析。固然,Cocoa框架下關於設計模式的內容遠遠不止這些,咱們選擇了經常使用的幾種:單例模式、委託模式、觀察者模式、MVC模式。ios
委託模式編程
委託模式從GoF 設計裝飾(Decorator)、適配器(Adapter)和模板方法(Template Method)等模式演變而來。幾乎每個應用都會或多或少地使用到委託模式。不僅是CocoaTouch框架,在Cocoa框架中委託模式也獲得了普遍的應用。設計模式
問題提出app
對於應用生命週期的非運行狀態——應用啓動場景,咱們把從點擊圖標到第一個畫面啓動的過程細化了一下框架
假設上圖這一系列的處理,都是在一個上帝類UIApplication完成的。之因此叫「上帝類(God Class)」,是由於它「無所不能」、「包含全部」。 在面向對象的軟件設計中「上帝類」不是很友好, 須要重構。在編程過程當中要儘可能避免上帝類的使用,由於上帝類是高耦合的,職責不清,因此難以維護。咱們須要「去除上帝類」,把看似功能很強且很難維護的 類,按照職責把本身的屬性或方法分派到各自的類中或分解成功能明確的類,從而去掉「上帝類」。ide
幸運的是蘋果沒有把UIApplication類設計成「上帝類」,蘋果處理分割到兩個不一樣的角色類中,其中一個扮演框架類角色,框架類具備通用、 可重複使用、與具體應用無關等特色。另外一個扮演應用相關類的角色,應用相關類與具體應用有關,因爲要受到框架類的控制,經常被設計成爲「協議」,在 Java中稱之爲「接口」。開發人員須要在具體的應用中實現這個「協議」。ui
將application:didFinishLaunchingWithOptions:和 applicationDidBecomeActive:完成功能提取出來,定義在UIApplicationDelegate協議中,這樣 UIApplication類就變成了框架類。編碼
在具體使用時候須要實現UIApplicationDelegate協議,HelloWorld應用的類圖。UIApplication不直接依賴 於AppDelegate類,而是依賴於UIApplicationDelegate協議,這在面向對象軟件設計原則中叫作「面向接口的編程」。 AppDelegate類實現協議UIApplicationDelegate,它是委託類。atom
咱們給出委託的定義,委託是爲了下降一個對象的複雜度和耦合度,使其可以更具通用性將其中一些處理置於委託對象中的編碼方式。通用類由於通用性即與 具體應用的無關性而變爲框架類,框架類保持委託對象的引用,並在特定時刻向委託對象發送消息。消息可能只是通知委託對象作一些事情,也多是對委託對象進 行控制。spa
實現原理
咱們經過一個案例介紹委託設計模式實現原理和應用場景,從新繪製委託設計模式類圖。
在古希臘有一個哲學家,他畢生只作三件事情:「睡覺」、「吃飯」和「工做」。爲更好的生活,工做效率更高,他會找一個徒弟,把這些事情委託給徒弟作。然而要成爲他的徒弟,須要實現一個協議,協議要求可以處理「睡覺」、「吃飯」和「工做」問題。 三者之間的關係。
哲學家類圖中, 通用類(Philosopher)保持指向委託對象(ViewController)的「弱引用」 (id<PhilosopherDelegate> delegate),委託對象(ViewController)就是哲學家的「徒弟」,他實現了協議 PhilosopherDelegate,PhilosopherDelegate規定了3個方法:-(void) sleep、-(void) eat和-(void) work方法。
下面咱們看看實現代碼,委託協議PhilosopherDelegate.h代碼以下:
- @protocol PhilosopherDelegate
- @required
- -(void) sleep;
- -(void) eat;
- -(void) work;
- @end
委託協議PhilosopherDelegate定義了3個方法,協議沒有m文件,它的定義能夠放在別的h文件中。它的實現類就是委託類ViewController的代碼以下:
- //
- // ViewController.h
- //
- @interface ViewController : UIViewController<PhilosopherDelegate>
- @end
- //
- // ViewController.m
- //
- @implementation ViewController
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- Philosopher *obj = [[Philosopher alloc ] init];
- obj.delegate = self;
- [obj start];
- }
- #pragma — PhilosopherDelegate 方法實現
- -(void) sleep
- {
- NSLog(@」sleep…」);
- }
- -(void) eat
- {
- NSLog(@」eat…」);
- }
- -(void) work
- {
- NSLog(@」work…」);
- }
- @end
委託對象如何與通用類創建引用關係呢?咱們經過viewDidLoad方法中的obj.delegate = self語句來指定委託對象和通用類間的引用關係。 通常狀況下通用類由框架直接提供,在這個例子中咱們根據須要本身實現了通用類Philosopher,Philosopher.h的代碼:
- //
- // Philosopher.h
- // DelegatePattern
- //
- #import 「PhilosopherDelegate.h」
- @interface Philosopher : NSObject
- {
- NSTimer *timer;
- int count;
- }
- @property (nonatomic, weak) id<PhilosopherDelegate> delegate;
- -(void) start;
- -(void) handle;
- @end
Philosopher.h中定義delegate屬性,它的類型是id<PhilosopherDelegate>,它能夠保存委託對象的引用,屬性weak說明是「弱引用」。Philosopher.m文件代碼以下:
- //
- // Philosopher.m
- // DelegatePattern
- #import 「Philosopher.h」
- @implementation Philosopher
- @synthesize delegate;
- -(void) start
- {
- count= 0;
- timer = [NSTimer scheduledTimerWithTimeInterval:3.0
- target:self selector:@selector(handle)userInfo:nil repeats:YES];
- }
- -(void)handle
- {
- switch (count)
- {
- case 0:
- [self.delegate sleep];
- count++;
- break;
- case 1:
- [self.delegate eat];
- count++;
- break;
- case 2:
- [self.delegate work];
- [timer invalidate];
- break;
- }
- }
- @end
在本例中Philosopher模擬一些通用類發出調用,這個調用的發出是經過NSTimer每3秒發出一個,依次向委託對象發出消息sleep、 eat和work。代碼中self.delegate是指向委託對象ViewController的引用,[self.delegate sleep]是調用ViewController中的sleep方法。