自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Objective-C學(xué)習(xí)之路 委托模式

移動(dòng)開發(fā) iOS
本文介紹的是Objective-C學(xué)習(xí)之路 委托模式,在Objective-C中,經(jīng)常提到委托模式(delegate),非常重要,我們來看內(nèi)容詳解。

Objective-C學(xué)習(xí)之路 委托模式是本文要介紹內(nèi)容,委托模式很重要,比如官方交互API,委托模式使用的很常見,比如UIView的setAnimationDelegate,設(shè)置動(dòng)畫的委托。不理解委托模式,就不能很快的理解很多API的使用,因?yàn)樗鼈兪褂靡粯拥哪J?,了解這個(gè)模式,就會(huì)心領(lǐng)神會(huì),立即上手。

下面用通俗的話說說委托模式是干什么用的。實(shí)際上Objective-C中的委托模式,類似于Java中的回調(diào)(CallBack)機(jī)制,或者說監(jiān)聽器機(jī)制。再或者說,類似JavaScript語言里面的onclick事件和函數(shù)的作用。比如要實(shí)現(xiàn)點(diǎn)擊一個(gè)按鈕之后做什么事情,這里肯定有個(gè)視圖類,有個(gè)控制類,無論你是使用什么語言和開發(fā)工具。視圖類能知道用戶什么時(shí)候點(diǎn)擊了按鈕,但是不知道點(diǎn)擊了以后做什么,控制類知道點(diǎn)擊按鈕后做什么,而不知道何時(shí)用戶會(huì)點(diǎn)擊。那么,可以將控制類委托給視圖類,當(dāng)點(diǎn)擊的時(shí)候視圖類調(diào)用控制類。

如果使用過Java的Swing等做本地圖形界面開發(fā),應(yīng)該知道在視圖類中包含了大量的(匿名)內(nèi)部類,或者要注冊(cè)監(jiān)聽器,這些機(jī)制起到和Objective-C委托類似的功效??梢赃@樣理解:監(jiān)聽器、(匿名)內(nèi)部類是實(shí)現(xiàn)怎么做的部分,但是不知道何時(shí)會(huì)發(fā)生事情,視圖類在事件發(fā)送時(shí)調(diào)用監(jiān)聽器、(匿名)內(nèi)部類,視圖類是知道何時(shí)發(fā)生事情的。

寫個(gè)簡(jiǎn)單的示例,是在main方法里寫的,模擬一下委托在視圖和控制中的作用。這里面,我有一個(gè)屏幕(Screen)類,就把它當(dāng)視圖吧。需求是當(dāng)點(diǎn)擊屏幕的時(shí)候爆炸。那么我有個(gè)動(dòng)作(Action)類,它會(huì)實(shí)現(xiàn)爆炸動(dòng)作。

用協(xié)議實(shí)現(xiàn)委托模式

下面的代碼寫的很生硬,后面會(huì)逐漸演化為合理的實(shí)現(xiàn)。第一個(gè)示例只是想說明技術(shù)上如何實(shí)現(xiàn),沒有實(shí)際運(yùn)用上的意義。

這里因?yàn)槭悄M,可以把main方法看作是用戶再操作界面,通過點(diǎn)擊創(chuàng)建了個(gè)視圖(Screen),然后調(diào)用Screen的實(shí)例方法onTouch,這里模擬用戶用手點(diǎn)擊了屏幕:

  1. #import <Foundation/Foundation.h>   
  2. #import "Screen.h"  
  3. int main (int argc, const char * argv[]) {   
  4.     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];  
  5.     Screen *screen=[[Screen alloc] init];   
  6.     screenscreen.delegate=screen;   
  7.     [screen onTouch];   
  8.     [screen release];   
  9.     [pool drain];   
  10.     return 0;   

這里先不用管:

  1. screenscreen.delegate=screen; 

后面再說。

Action類,在這里用協(xié)議來實(shí)現(xiàn):

  1. #import <Cocoa/Cocoa.h> 
  2. @protocol Action <NSObject> 
  3. - (void) doAction;  
  4. @end 

是一個(gè)協(xié)議,該協(xié)議繼承了NSObject協(xié)議。這里要注意,NSObject在這里不是類,確實(shí)有同名類。這個(gè)協(xié)議定義了一個(gè)doAction方法,這個(gè)方法可實(shí)現(xiàn)比如“屏幕爆炸”的需求。

下面說說屏幕(Screen)類,頭文件:

  1. #import <Foundation/Foundation.h>   
  2. #import "Action.h"  
  3. @interface Screen : NSObject <Action> {   
  4.     id <Action> delegate;   
  5. }  
  6. @property(nonatomic,retain) id <Action> delegate;  
  7. - (void) onTouch;  
  8. @end 

這里的onTouch方法,就是模擬Screen被用戶點(diǎn)擊后調(diào)用的方法。Screen類實(shí)現(xiàn)了Action協(xié)議。然后它還有個(gè)Action類型的成員delegate。為了能設(shè)置delegate實(shí)例變量,還為它設(shè)置了property。

下面看看實(shí)現(xiàn)文件:

  1. #import "Screen.h"  
  2. @implementation Screen  
  3. @synthesize delegate;  
  4. - (void) onTouch{   
  5.     NSLog(@"on touch …");   
  6.     if ([delegate conformsToProtocol:@protocol(Action)] &&   
  7.         [delegate respondsToSelector:@selector(doAction)]) {   
  8.         [delegate performSelector:@selector(doAction)];   
  9.     }   
  10.     NSLog(@"on touched.");   
  11. }  
  12. - (void) doAction{   
  13.     NSLog(@"Bang!!!!!!!!!");   
  14. }  
  15. @end 

這里重點(diǎn)看onTouch方法內(nèi)部代碼,要判斷delegate是否是Action協(xié)議,而且是否有doAction方法,這個(gè)判斷夠嚴(yán)謹(jǐn)了。如果正確,就調(diào)用Action協(xié)議的doAction方法。

實(shí)際上未必要讓Screen實(shí)現(xiàn)Action協(xié)議,雖然開發(fā)中經(jīng)常是類似這樣的做法。任意的實(shí)現(xiàn)Action協(xié)議的類實(shí)例都可以設(shè)置給screen的delegate屬性。

上面的示例和開發(fā)中碰到的情況不很像,實(shí)際情況往往類似下面示例的樣子。首先看看main方法:

  1. #import <Foundation/Foundation.h>   
  2. #import "MyScreen.h"  
  3. int main (int argc, const char * argv[]) {   
  4.     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];  
  5.     Screen *screen=[[MyScreen alloc] init];  
  6.     [screen onTouch];   
  7.     [screen release];   
  8.     [pool drain];   
  9.     return 0;   

這里發(fā)現(xiàn)增加了個(gè)MyScreen 類。它繼承自Screen類。這里的代碼不再設(shè)置delegate屬性,因?yàn)橐呀?jīng)在MyScreen類的init方法中設(shè)置了。后面會(huì)看到。

Action協(xié)議沒有變化,只是增加了optional:

  1. #import <Cocoa/Cocoa.h> 
  2. @protocol Action <NSObject> 
  3. @optional   
  4. - (void) doAction;  
  5. @end 

Screen類,可以看作抽象類,它主要供繼承使用,來復(fù)用委托模式的代碼。頭文件:

  1. #import <Foundation/Foundation.h>   
  2. #import "Action.h"  
  3. @interface Screen : NSObject <Action> {   
  4.     id <Action> delegate;   
  5. }  
  6. @property(nonatomic,retain) id <Action> delegate;  
  7. - (void) onTouch;  
  8. @end  

實(shí)現(xiàn)文件:

  1. #import "Screen.h"  
  2. @implementation Screen  
  3. @synthesize delegate;  
  4. - (void) onTouch{   
  5.     NSLog(@"on touch …");   
  6.     if ([delegate conformsToProtocol:@protocol(Action)] &&   
  7.         [delegate respondsToSelector:@selector(doAction)]) {   
  8.         [delegate performSelector:@selector(doAction)];   
  9.     }   
  10.     NSLog(@"on touched.");   
  11. }  
  12. @end 

這里不再實(shí)現(xiàn)doAction方法。

下面看MyScreen類的頭文件:

  1. #import <Cocoa/Cocoa.h>   
  2. #import "Screen.h"  
  3.  
  4. @interface MyScreen : Screen {  
  5. }  
  6. @end 

MyScreen類的實(shí)現(xiàn)文件:

  1. #import "MyScreen.h"  
  2. @implementation MyScreen  
  3. - (id) init{   
  4.     if (self=[super init]) {   
  5.         delegate=self;   
  6.     }   
  7.     return self;   
  8. }  
  9. - (void) doAction{   
  10.     NSLog(@"Bang!!!!!!!!!");   
  11. }  
  12. @end 

用類別實(shí)現(xiàn)委托模式

可以使用類別(Category)實(shí)現(xiàn)委托模式。還是上面的例子。下面使用Category實(shí)現(xiàn)了個(gè)示例。

main方法:

  1. int main (int argc, const char * argv[]) {   
  2.     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];  
  3.  
  4.     Screen *screen=[[Screen alloc] init];  
  5.     [screen onTouch];   
  6.     [screen release];    
  7.     [pool drain];   
  8.     return 0;   

Screen類的頭文件:

  1. #import <Foundation/Foundation.h> 
  2. @interface Screen : NSObject {   
  3.     id delegate;   
  4. }  
  5. @property(nonatomic,retain) id delegate;  
  6. - (void) onTouch;  
  7. @end 

在這個(gè)示例中,實(shí)際上property沒有起什么作用。

實(shí)現(xiàn)文件:

  1. #import "Screen.h"  
  2. @implementation Screen  
  3. @synthesize delegate;  
  4. - (id) init{   
  5.     if (self=[super init]) {   
  6.         delegate=self;   
  7.     }   
  8.     return self;   
  9. }  
  10. - (void) onTouch{   
  11.     NSLog(@"on touch …");   
  12.     if ([delegate respondsToSelector:@selector(doAction)]) {   
  13.         [delegate performSelector:@selector(doAction)];   
  14.     }   
  15.     NSLog(@"on touched.");   
  16. }  
  17. @end  

寫到這里,如果運(yùn)行代碼,只會(huì)打印類似下面的日志:

  1. 2011-05-26 10:37:30.843 DelegateDemo[5853:a0f] on touch …   
  2. 2011-05-26 10:37:30.846 DelegateDemo[5853:a0f] on touched. 

下面寫Category代碼,名稱為ScreenAction,它的頭文件:

  1. #import <Cocoa/Cocoa.h>   
  2. #import "Screen.h"  
  3. @interface Screen (ScreenAction)   
  4. - (void) doAction;  
  5. @end 

實(shí)現(xiàn)文件:

  1. #import "ScreenAction.h"  
  2. @implementation Screen (ScreenAction)  
  3.  
  4. - (void) doAction{   
  5.     NSLog(@"BANG!!!!!!");   
  6. }  
  7. @end 

實(shí)現(xiàn)了這部分代碼再執(zhí)行:

  1. 2011-05-26 10:37:30.843 DelegateDemo[5853:a0f] on touch …   
  2. 2011-05-26 10:37:30.846 DelegateDemo[5853:a0f] BANG!!!!!!   
  3. 2011-05-26 10:37:30.846 DelegateDemo[5853:a0f] on touched. 

小結(jié):Objective-C學(xué)習(xí)之路 委托模式的內(nèi)容介紹完了,希望本文對(duì)你有所幫助。

責(zé)任編輯:zhaolei 來源: 互聯(lián)網(wǎng)
相關(guān)推薦

2011-07-25 13:05:37

Objective-C 委托

2011-07-25 10:14:13

Objective-C Xcode

2011-07-25 10:30:41

Objective-C Xcode 重構(gòu)

2011-07-25 11:02:29

Objective-C Xcode 標(biāo)簽

2011-08-03 15:51:48

Objective-C 協(xié)議 委托

2011-08-15 14:32:42

Objective-C委托協(xié)議

2011-08-04 14:58:37

Objective-C Cocoa NSString

2013-08-21 14:57:42

objective-c問題

2011-05-11 14:06:49

Objective-C

2011-08-05 14:03:39

Objective-C 對(duì)象 模板

2011-08-16 10:23:04

Objective-CNSAutoreleaXcode常用鍵

2011-07-06 14:41:34

Objective-C

2011-08-15 17:06:01

Objective-CNSLog

2013-03-26 10:35:47

Objective-C單例實(shí)現(xiàn)

2011-08-10 18:07:29

Objective-C反射

2011-05-11 15:58:34

Objective-C

2013-03-27 12:54:00

iOS開發(fā)Objective-C

2013-06-20 10:40:32

Objective-C實(shí)現(xiàn)截圖

2011-05-11 11:20:26

Objective-C

2011-08-04 10:57:33

Objective-C C語言 BOOL
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)