1. 程式人生 > >關於 iOS delegate 的遐想

關於 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 兩種玩法,也挺有意思。