OC學習篇之---代理模式,oc---代理
在前一篇文章我們介紹了OC中的協議的概念:http://blog.csdn.net/jiangwei0910410003/article/details/41776015,這篇文章我們就來介紹一下OC中的代理模式,關於代理模式,如果還有同學不太清楚的話,就自己去補充知識了,這裡就不做介紹了,這裡只介紹OC中是如何?代理模式的。
這裡舉一個簡單的例子:
小孩類,護士類,保姆類,其中小孩類有兩個方法:wash和play
這裡代理對象就是:護士類、保姆類,小孩類是被代理對象。
看一下代碼:
首先看一下小孩類:
Children.h
//// Children.h// 12_DesignStyle//// Created by jiangwei on 14-10-11.// Copyright (c) 2014年 jiangwei. All rights reserved.//#import <Foundation/Foundation.h>@class Children;//如果沒有這行代碼的話,協議ChildrenDelegate中得Children類型就會尋找不到,報錯@protocol ChildrenDelegate <NSObject>@required- (void)wash:(Children *)children;- (void)play:(Children *)children;@end@interface Children : NSObject{ //Nure *_nure;//保姆 //這裡可以使用多態技術實現,因為保姆,護士有共同的父類NSObject,但是這裡不使用這種方式,而是使用id類型 //但是我們還需要為這個類型添加一些方法,這裡就用到了協議 //這個代理對象必須遵從ChildrenDelegate協議 id<ChildrenDelegate> _delegate;//這個變數就是小孩的代理對象 NSInteger timeValue;}-(void)setDelegate:(id)delegate;@end這裡,我們定義了一個協議:ChildrenDelegate,他有兩個必要的方法:wash和play
我們還定義了一個很重要的屬性
_delegate
這個屬性定義有點不一樣,這個就是實現代理對象的精髓所在了,id是不確定類型,所以這個_delegate變數可以被賦值為的類型是:
只要實現了ChildrenDelegate協議的類就可以了。這裡就記住了,以後這種定義方法後面會用到很多。相當於Java中的介面類型,只能賦值其實作類別的類型。只是這裡的定義格式為:id<協議名>
然後就是一個設定協議的方法了,注意參數類型也必須是id的
其實這裡面也牽涉到了之前說到的多態特性,所以說代理模式也是建立在多態的特性上的。
Children.m
//// Children.m// 12_DesignStyle//// Created by jiangwei on 14-10-11.// Copyright (c) 2014年 jiangwei. All rights reserved.//#import "Children.h"//這裡用到了保姆的一些動作//假如現在想請一個護士,那麼我們又要去從新去請一個護士,那麼這裡面代碼需要改,把保姆的地方換成護士的地方//產生的原因就是因為耦合度太高了,保姆和孩子耦合在一起,如果需要換的話,就需要改動代碼//@implementation Children- (id)init{ self = [super init]; if(self != nil){ [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES]; } return self;}-(void)setDelegate:(id)delegate{ _delegate = delegate;}- (void)timerAction:(NSTimer *)timer{ timeValue++; if(timeValue == 5){ [_delegate wash:self]; } if(timeValue == 10){ [_delegate play:self]; }}@end我們自訂了一個初始化方法,在初始化方法中我們做了一個定時器的工作。
[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
//// Nure.h// 12_DesignStyle//// Created by jiangwei on 14-10-11.// Copyright (c) 2014年 jiangwei. All rights reserved.//#import <Foundation/Foundation.h>#import "Children.h"@interface Nure : NSObject<ChildrenDelegate>- (void)wash:(Children *)children;- (void)play:(Children *)children;@end
護士類很簡單,實現ChildrenDelegate協議
Nure.m
//// Nure.m// 12_DesignStyle//// Created by jiangwei on 14-10-11.// Copyright (c) 2014年 jiangwei. All rights reserved.//#import "Nure.h"#import "Children.h"@implementation Nure- (void)wash:(Children *)children{ NSLog(@"小孩髒了,保姆幫小孩洗澡");}- (void)play:(Children *)children{ NSLog(@"小孩哭了,保姆和小孩玩耍");}@end在這裡就去實現wash和play方法了
在來看一下保姆類:
Nanny.h
//// Nanny.h// 12_DesignStyle//// Created by jiangwei on 14-10-11.// Copyright (c) 2014年 jiangwei. All rights reserved.//#import <Foundation/Foundation.h>#import "Children.h"@interface Nanny : NSObject<ChildrenDelegate>- (void)wash:(Children *)children;- (void)play:(Children *)children;@end
Nanny.m
//// Nanny.m// 12_DesignStyle//// Created by jiangwei on 14-10-11.// Copyright (c) 2014年 jiangwei. All rights reserved.//#import "Nanny.h"#import "Children.h"@implementation Nanny- (void)wash:(Children *)children{ NSLog(@"小孩髒了,護士幫小孩洗澡");}- (void)play:(Children *)children{ NSLog(@"小孩哭了,護士和小孩玩耍");}@end保姆類和護士類的代碼邏輯是一樣的,因為他們兩個都是實現了一個協議
測試類別
main.m
//// main.m// 12_DesignStyle//// Created by jiangwei on 14-10-11.// Copyright (c) 2014年 jiangwei. All rights reserved.//#import <Foundation/Foundation.h>#import "Children.h"#import "Nure.h"#import "Nanny.h"//核心:id類型+協議//做到低耦合操作//同時也可以做到兩個類之間的通訊int main(int argc, const char * argv[]) { @autoreleasepool { Children *child = [[Children alloc] init]; Nure *nure = [[Nure alloc] init]; Nanny *nanny= [[Nanny alloc] init]; [child setDelegate:nanny];// [child setNure:nure]; [[NSRunLoop currentRunLoop] run]; } return 0;}看到了,測試類別很簡單。我們也發現了,代理模式的好處也是顯現出來了,比如現在又來了一個人來照顧孩子:媽媽類,那麼我們只要讓媽媽類實現那個協議即可。這種耦合度也不會很高。所以代理模式還是超級有用的,而且我們後面在開發IOS的時候,會發現他裡面用到的代理模式很多的。
運行結果:
總結
這一篇就介紹了OC中如何?代理模式,其實OC中的代理模式核心技術是:id類型+協議+多態