OC學習篇之---代理模式


這篇文章我們就來介紹一下OC中的代理模式,關於代理模式,如果還有同學不太清楚的話,就自己去補充知識了,這里就不做介紹了,這里只介紹OC中是如何實現代理模式的。

這里舉一個簡單的例子:

小孩類,護士類,保姆類,其中小孩類有兩個方法:wash和play

這里代理對象就是:護士類、保姆類,小孩類是被代理對象。

看一下代碼:

首先看一下小孩類:

Children.h

 

[objc]  view plain  copy
  1. //  
  2. //  Children.h  
  3. //  12_DesignStyle  
  4. //  
  5. //  Created by jiangwei on 14-10-11.  
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
  7. //  
  8.   
  9. #import <Foundation/Foundation.h>  
  10.   
  11. @class Children;//如果沒有這行代碼的話,協議ChildrenDelegate中得Children類型就會查找不到,報錯  
  12.   
  13. @protocol ChildrenDelegate <NSObject>  
  14.   
  15. @required  
  16. - (void)wash:(Children *)children;  
  17. - (void)play:(Children *)children;  
  18.   
  19. @end  
  20.   
  21. @interface Children : NSObject{  
  22.       
  23.     //Nure *_nure;//保姆  
  24.     //這里可以使用多態技術實現,因為保姆,護士有共同的父類NSObject,但是這里不使用這種方式,而是使用id類型  
  25.     //但是我們還需要為這個類型添加一些方法,這里就用到了協議  
  26.     //這個代理對象必須遵從ChildrenDelegate協議  
  27.     id<ChildrenDelegate> _delegate;//這個變量就是小孩的代理對象  
  28.     NSInteger timeValue;  
  29. }  
  30.   
  31. -(void)setDelegate:(id)delegate;  
  32.   
  33. @end  

這里,我們定義了一個協議:ChildrenDelegate,他有兩個必要的方法:wash和play

 

我們還定義了一個很重要的屬性

_delegate

這個屬性定義有點不一樣,這個就是實現代理對象的精髓所在了,id是不確定類型,所以這個_delegate變量可以被賦值為的類型是:

只要實現了ChildrenDelegate協議的類就可以了。這里就記住了,以后這種定義方法后面會用到很多。相當於Java中的接口類型,只能賦值其實現類的類型。只是這里的定義格式為:id<協議名>

然后就是一個設置協議的方法了,注意參數類型也必須是id的

其實這里面也牽涉到了之前說到的多態特性,所以說代理模式也是建立在多態的特性上的。

 

Children.m

 

[objc]  view plain  copy
  1. //  
  2. //  Children.m  
  3. //  12_DesignStyle  
  4. //  
  5. //  Created by jiangwei on 14-10-11.  
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
  7. //  
  8.   
  9. #import "Children.h"  
  10.   
  11. //這里用到了保姆的一些動作  
  12. //假如現在想請一個護士,那么我們又要去從新去請一個護士,那么這里面代碼需要改,把保姆的地方換成護士的地方  
  13. //產生的原因就是因為耦合度太高了,保姆和孩子耦合在一起,如果需要換的話,就需要改動代碼  
  14. //  
  15. @implementation Children  
  16.   
  17. - (id)init{  
  18.     self = [super init];  
  19.     if(self != nil){  
  20.         [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];  
  21.     }  
  22.     return self;  
  23. }  
  24.   
  25. -(void)setDelegate:(id)delegate{  
  26.     _delegate = delegate;  
  27. }  
  28.   
  29. - (void)timerAction:(NSTimer *)timer{  
  30.     timeValue++;  
  31.     if(timeValue == 5){  
  32.         [_delegate wash:self];  
  33.     }  
  34.     if(timeValue == 10){  
  35.         [_delegate play:self];  
  36.     }  
  37. }  
  38.   
  39. @end  

我們自定義了一個初始化方法,在初始化方法中我們做了一個定時器的工作。

 

 

[java]  view plain  copy
  1. [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];  

這個就是OC中啟動一個簡單的計時器:每隔1s中就去執行一次self中的timerAction方法。

 

OC中的定時器和java不一樣,他的執行邏輯可以單獨的在一個指定的方法中去做(C中的函數指針差不多,只要傳遞一個函數指針過來,就可以執行指定的函數,所以@selector做的工作就是這個),但是Java中必須實現Runable接口,在run方法中執行指定的邏輯代碼。

在timerAction方法中,我們是判斷當時間到5s了,就執行代理對象的wash方法,10s的時候執行play方法。

 

在來看一下護士類:

Nure.h

 

[objc]  view plain  copy
  1. //  
  2. //  Nure.h  
  3. //  12_DesignStyle  
  4. //  
  5. //  Created by jiangwei on 14-10-11.  
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
  7. //  
  8.   
  9. #import <Foundation/Foundation.h>  
  10.   
  11. #import "Children.h"  
  12.   
  13. @interface Nure : NSObject<ChildrenDelegate>  
  14.   
  15. - (void)wash:(Children *)children;  
  16. - (void)play:(Children *)children;  
  17.   
  18. @end  

護士類很簡單,實現ChildrenDelegate協議

 

 

Nure.m

 

[objc]  view plain  copy
  1. //  
  2. //  Nure.m  
  3. //  12_DesignStyle  
  4. //  
  5. //  Created by jiangwei on 14-10-11.  
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
  7. //  
  8.   
  9. #import "Nure.h"  
  10.   
  11. #import "Children.h"  
  12.   
  13. @implementation Nure  
  14.   
  15. - (void)wash:(Children *)children{  
  16.     NSLog(@"小孩臟了,保姆幫小孩洗澡");  
  17. }  
  18.   
  19. - (void)play:(Children *)children{  
  20.     NSLog(@"小孩哭了,保姆和小孩玩耍");  
  21. }  
  22.   
  23. @end  

在這里就去實現wash和play方法了

 

 

在來看一下保姆類:

Nanny.h

 

[objc]  view plain  copy
  1. //  
  2. //  Nanny.h  
  3. //  12_DesignStyle  
  4. //  
  5. //  Created by jiangwei on 14-10-11.  
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
  7. //  
  8.   
  9. #import <Foundation/Foundation.h>  
  10.   
  11. #import "Children.h"  
  12.   
  13. @interface Nanny : NSObject<ChildrenDelegate>  
  14.   
  15. - (void)wash:(Children *)children;  
  16. - (void)play:(Children *)children;  
  17.   
  18. @end  


Nanny.m

 

 

[objc]  view plain  copy
  1. //  
  2. //  Nanny.m  
  3. //  12_DesignStyle  
  4. //  
  5. //  Created by jiangwei on 14-10-11.  
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
  7. //  
  8.   
  9. #import "Nanny.h"  
  10.   
  11. #import "Children.h"  
  12.   
  13. @implementation Nanny  
  14.   
  15. - (void)wash:(Children *)children{  
  16.     NSLog(@"小孩臟了,護士幫小孩洗澡");  
  17. }  
  18.   
  19. - (void)play:(Children *)children{  
  20.     NSLog(@"小孩哭了,護士和小孩玩耍");  
  21. }  
  22.   
  23. @end  

保姆類和護士類的代碼邏輯是一樣的,因為他們兩個都是實現了一個協議

 

 

測試類

main.m

 

[objc]  view plain  copy
  1. //  
  2. //  main.m  
  3. //  12_DesignStyle  
  4. //  
  5. //  Created by jiangwei on 14-10-11.  
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
  7. //  
  8.   
  9. #import <Foundation/Foundation.h>  
  10.   
  11. #import "Children.h"  
  12. #import "Nure.h"  
  13. #import "Nanny.h"  
  14.   
  15. //核心:id類型+協議  
  16. //做到低耦合操作  
  17. //同時也可以做到兩個類之間的通信  
  18.   
  19. int main(int argc, const charchar * argv[]) {  
  20.     @autoreleasepool {  
  21.         Children *child = [[Children alloc] init];  
  22.           
  23.         Nure *nure = [[Nure alloc] init];  
  24.         Nanny *nanny= [[Nanny alloc] init];  
  25.           
  26.         [child setDelegate:nanny];  
  27. //      [child setNure:nure];  
  28.           
  29.         [[NSRunLoop currentRunLoop] run];  
  30.     }  
  31.     return 0;  
  32. }  

看到了,測試類很簡單。我們也發現了,代理模式的好處也是顯現出來了,比如現在又來了一個人來照顧孩子:媽媽類,那么我們只要讓媽媽類實現那個協議即可。這種耦合度也不會很高。所以代理模式還是超級有用的,而且我們后面在開發IOS的時候,會發現他里面用到的代理模式很多的。

 

 

運行結果:




總結

這一篇就介紹了OC中如何實現代理模式,其實OC中的代理模式核心技術是:id類型+協議+多態


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM