-
“太長不看!”污筷,我們盡量壓縮工闺,只講重點(diǎn)和基礎(chǔ)。
概念
大白話:我寫了一些粗糙的框架功能瓣蛀,給了你一個使用的接口陆蟆,由你來完成具體的細(xì)節(jié),而你就是我的delegate惋增,我委托你來做叠殷。
舉例
不上代碼的作者不是好程序員
下面附上代碼,大家如果有興致的話可以跟著一步一步做诈皿。
1.為方便起見林束,直接Xcode創(chuàng)建OS X Application下的Command Line Tool工程。
2.代碼非常簡單稽亏,分為A和B兩個類壶冒,A類提供粗糙接口,B完成具體功能截歉,實(shí)現(xiàn)A的委托胖腾,之后在main函數(shù)中使用它們。
3.A類:
- A.h
#import <Foundation/Foundation.h>
@protocol ADelegate <NSObject>
- (void)weDidGetSthFromA:(NSString *)sthFromA;
@end
@interface A : NSObject
@property (weak, nonatomic) id<ADelegate> delegate;
- (void)doSth;
@end
A.h在普通的頭文件的基礎(chǔ)上瘪松,增添了@protocol
關(guān)鍵字咸作,以聲明一個ADelegate
協(xié)議,協(xié)議顧名思義宵睦,如果某個類使用了該協(xié)議记罚,可以根據(jù)協(xié)議的要求,使用及實(shí)現(xiàn)協(xié)議的一些接口壳嚎。之后B就會使用ADelegate
這個協(xié)議桐智。 協(xié)議實(shí)現(xiàn)了一個名為 weDidGetSthFromA:
的方法。
注:在查看一些源碼時诬辈,有時會在方法明前看到@required
或者@optional
關(guān)鍵字酵使,它們表明委托在使用協(xié)議時,是否必須實(shí)現(xiàn)協(xié)議中的方法焙糟,@required
是必須口渔,@optional
是可選。
同時很重要的一點(diǎn)穿撮,在@interface A
中缺脉,由于要為A指派委托痪欲,因此需要聲明一個@property
,代碼中的@property
表明它屬于ADelegate
協(xié)議攻礼,名字叫delegate
业踢。
最后,A類定義了一個演示用的方法doSth
礁扮,它在這里不是重點(diǎn)知举。
- A.m
#import "A.h"
@implementation A
- (id)init
{
if (self = [super init])
{
//do sth
}
return self;
}
- (void)doSth
{
[self.delegate weDidGetSthFromA:@"B, 做點(diǎn)什么吧!"];
}
@end
A.m文件中普通的init
,關(guān)鍵處請注意- (void)doSth
函數(shù)太伊,乍一看它很普通雇锡,就一行代碼,但恰恰是這一行代碼僚焦,包含了delegate的精髓锰提。
還記得delegate的含義嗎?在這里A委托B做事情芳悲,A只提供必要的接口立肘,B是A的delegate,因此在A中名扛,A覺得“嗯谅年!之后總會有誰會幫我完成更加具體的功能的,我在這里提供接口就行了”罢洲,于是A就在- (void)doSth
函數(shù)中踢故,默默讓它的代理:self.delegate
文黎,執(zhí)行了相應(yīng)的接口函數(shù)weDidGetSthFromA
(即協(xié)議里面那個方法)惹苗。
之后,A只要執(zhí)行doSth
方法耸峭,A的delegate(此示例只能一對一桩蓉,即一個代理),即后文的B就能獲取weDidGetSthFromA
這個方法包含的信息劳闹,我們稱之為回調(diào)院究。
4.B類:
- B.h
#import <Foundation/Foundation.h>
#import "A.h"
@interface B : NSObject <ADelegate>
@end
B.h @interface B : NSObject <ADelegate>
關(guān)鍵的一行,表明B遵循ADelegate
協(xié)議本涕。
- B.m
#import "B.h"
@implementation B
- (id)init
{
if (self = [super init])
{
//do sth
}
return self;
}
- (void)weDidGetSthFromA:(NSString *)sthFromA
{
NSLog(@"A告訴B: %@", sthFromA);
}
@end
B.m也是普通的init
业汰,關(guān)鍵點(diǎn)就是因?yàn)樵陬^文件中遵循ADelegate
協(xié)議,因此它可以使用weDidGetSthFromA
方法菩颖。在A.m中样漆,A覺得它的代理會如上述那么做,因此A給B傳了一個NSString@"B, 做點(diǎn)什么吧!"
晦闰,在這里B可以獲取這個回調(diào)放祟,并在這里NSLog
打印了出來鳍怨。
5.main函數(shù)
#import <Foundation/Foundation.h>
#import "A.h"
#import "B.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
A *a = [[A alloc] init];
B *b = [[B alloc] init];
a.delegate = b;
[a doSth];
}
return 0;
}
OK,終于到了main 函數(shù)跪妥,A和B普通地實(shí)例化鞋喇,關(guān)鍵的一行則是:a.delegate = b;
如上述,一切都做好了眉撵,就差一步侦香,那就是究竟誰做a的代理呢,那么這一行代碼就說明了一切纽疟,b是a的代理鄙皇,b來具體使用weDidGetSthFromA
方法。
下面一行仰挣,[a doSth];
執(zhí)行這個方法后伴逸,a就向b傳遞了@"B, 做點(diǎn)什么吧!"
這個NSString
,然后b就打印出來膘壶。
大家可以運(yùn)行一下代碼错蝴,看看輸出的情況。
總結(jié)
初次使用delegate颓芭,可能會有點(diǎn)摸不著頭腦顷锰,不知道“回調(diào)”是什么,其實(shí)它們就是提供接口與使用接口的關(guān)系亡问。
希望這篇文章能給大家?guī)硪稽c(diǎn)點(diǎn)幫助官紫。感謝閱讀!
如轉(zhuǎn)發(fā)州藕,請注明出處束世。