關於 iOS delegate 的遐想
Delegate 作為iOS 系統中一種非常常用的設計模式,在很多地方使用的地方非常的多。
之前剛開始接觸OC 的時候,對於這個delegate模式非常的不理解,不知道這個所謂的delegate 是用來幹嘛的。
不過做了幾年的iOS開發後,對於這一塊也算是有自己的理解了。
首先 delegate 的定義是一個繼承特定介面的物件。
比如定義瞭如下介面:
然後在另外一個物件裡面,有這麼一個屬性繼承自這個介面:#ifndef Protocol_h #define Protocol_h @protocol TestProtocol <NSObject> -(void)firstInterface; -(void)secondInterface; @end
#import <Foundation/Foundation.h>
#import "Protocol.h"
@interface TestClass : NSObject
@property (nonatomic,weak) id<TestProtocol>delegate;
@end
這樣的好處就像一個一把起子,對於只要符合這個起子的螺絲釘,不管是長的短的,都可以操作,因為這些螺絲釘都的介面(對應我們的 protocol)都一樣,在適當的時候可以進行替換。 所以 delegate 有一種面向抽象程式設計的意思,物件是不具體的但是介面是定義好的。
除此之外。 delegate 還可以做
大家常說的delegate模式,其實也就是這個意思。不過delegate模式不是一種模式,它是兩種分別不同的功能。
第一點個就是回撥。
A 有一件事情自己辦不了,要找B 幫忙辦理,辦理完之後B得把結果告訴A ,然後通過delegate 找到A。
這裡的delegate 就是A, 要得到結果,就得實現B提供的介面,這個介面是B呼叫A 用來告訴A結果的。
首先是類B 它是一個工具一樣的東西,能夠幫忙幹活,然後幹完活通知 讓他幹活的那個 物件,就是A
它的實現如下:
#import <Foundation/Foundation.h> @protocol ResultProtocal <NSObject> @optional -(void)addResult:(NSInteger)value; -(void)mutiplayResult:(NSInteger)value; @end @interface ObjectB : NSObject ///計算兩個數之和 -(void)caculateAdd:(NSInteger)a value:(NSInteger)b; ///計算兩個數的乘積 -(void)caculateMultiply:(NSInteger)a value:(NSInteger)b; @property (nonatomic,weak) id<ResultProtocal>delegate; @end
#import "ObjectB.h"
@implementation ObjectB
///計算兩個數之和
-(void)caculateAdd:(NSInteger)a value:(NSInteger)b
{
if (self.delegate && [self.delegate respondsToSelector:@selector(addResult:)]) {
[self.delegate addResult:(a+b)];
}
}
///計算兩個數的乘積
-(void)caculateMultiply:(NSInteger)a value:(NSInteger)b
{
if (self.delegate && [self.delegate respondsToSelector:@selector(mutiplayResult:)]) {
[self.delegate addResult:(a*b)];
}
}
@end
A 呢,A只管讓B 幹事情就行了,但是幹完事B 得告訴A 啊,所以A得 實現函式,讓B 告訴自己結果:
A的實現如下:
#import "ObjectA.h"
#import "ObjectB.h"
@interface ObjectA()<ResultProtocal>
@end
@implementation ObjectA
-(void)mainFunction
{
ObjectB *b = [ObjectB new];//建立一個執行任務的物件
b.delegate = self;//告訴B 你任務完成了之後找我就行了
[b caculateAdd:100 value:200];//b 開始執行任務
}
/// 物件A 實現 工具B 完成任務的結果呼叫函式
-(void)addResult:(NSInteger)value
{
}
-(void)mutiplayResult:(NSInteger)value
{
}
@end
好了這是第一種 delegate 的應用場景,看起來有一點非同步工作的概念,事情交給你幹,結果告訴我就得了。
這也是一種面向介面的程式設計。 比如同一種計算方法: 不僅可以有ObjectB 也許還有ObjectD 或者 ObjectE呢,也是可以的
他們雖然都提供了計算方法,但是對於不同的場景,也許計算的實現不一樣,有的可以用二進位制,有的可以用遞迴,有的可以使用
更高階的演算法等等不一而論,具有可變性。
另外一種delegate 的使用方法,有點強盜的意味。還是A 和 B 但是呢,但是呢這裡的角色得調換一下位置。
當然 A 仍然是 delegate 但是 這個時候 A 變成了幹活的那一方。
這很神奇麼?這不神奇。 這個時候,A 集成了方法,並且實現了方法,B中仍然有一個delegate物件,這個物件就是A。
下面看A程式碼:
#import "ObjectA.h"
#import "ObjectB.h"
@interface ObjectA()
@end
@implementation ObjectA
-(NSString*)todayIs
{
return @"Friday";
}
-(NSString*)tomorroyIs
{
return @"Saturday";
}
@end
再來看看B的程式碼:
#import <Foundation/Foundation.h>
@protocol ResultProtocal <NSObject>
@optional
-(NSString*)todayIs;
-(NSString*)tomorroyIs;
@end
@interface ObjectB : NSObject
@property (nonatomic,weak) id<ResultProtocal>delegate;
@end
#import "ObjectB.h"
@implementation ObjectB
-(void)mainFunction
{
/// 一開始很閒,突然想知道 今天周幾了,那好吧,讓A 告訴我
if (self.delegate && [self.delegate respondsToSelector:@selector(todayIs)]) {
NSString *today = [self.delegate todayIs];
NSLog(@"%@",today);
}
}
@end
B 搖身一遍稱為了讓A 幹活的人。。。
從程式碼中可以看到 第二種情況, 定義的協議的函式實現,都有返回值。 這是和第一種情況不一樣的地方。
而且 B 的這種呼叫方式,很像 同步操作。
一個delegate 兩種玩法,也挺有意思。