引入幾個概念
-
協(xié)議方
協(xié)議方最好另起一個.h 针贬,協(xié)議方內(nèi)的optional / required,我稱它為——協(xié)議函數(shù)——,這里只有聲明協(xié)議函數(shù)
-
委托方
——委托函數(shù)——著角,就是上面的 doWork , ——委托函數(shù)—— 中讓代理去實現(xiàn)協(xié)議方的——協(xié)議函數(shù)—— : doSomeRequiredWork/doSomeOptionalWork
-
代理方
新建一個委托方類事富,實現(xiàn) ——協(xié)議函數(shù)——
下面是說明
-
協(xié)議方
協(xié)議方?jīng)]什么好說的技俐,格式正確即可
-
委托方
** 委托方不實現(xiàn)協(xié)議,代理方是委托方的屬性變量统台,通過后續(xù)賦值來實例化之 **
- 協(xié)議要么單獨(dú)寫一個.h雕擂,要么寫在委托方,最后代理方導(dǎo)入委托方的.h贱勃。避免多個代理的時候井赌,委托方要導(dǎo)入很多次(看個人習(xí)慣谤逼,我覺得這樣寫比較好)
- 下面是完整的委托方代碼 注意第四行
代理方 是 委托方的屬性變量,委托方必須遵循協(xié)議方的內(nèi)容3鹚搿A鞑俊!
/*****************************************************************/
// ———————————————————— Manager.h 類 ————————————————————
@interface Manager:NSObject
//代理方 是 委托方的屬性變量纹坐,委托方必須遵循協(xié)議方的內(nèi)容V健!耘子!
@property (strong,nonatomic) id<JobContent> delegate;
-(void)doWork;
@end
// ———————————————————— Manager.m 類 ————————————————————
#import Manager.h
@implementation Manager
-(void)doWork // 委托函數(shù)宾茂,有些情況是需要傳參
{
[self.delegate doSomeRequiredWork];// 1. 代理方必須實現(xiàn)的內(nèi)容!
// 2. 判斷某個代理方是否存在可選實現(xiàn)的內(nèi)容 拴还!
if ([self.delegate respondsToSelector:@selector(doSomeOptionalWork)])
{
[self.delegate doSomeOptionalWork];//存在跨晴,執(zhí)行worker可選的內(nèi)容
}
[self myWork]; // 3. 委托方自己要實現(xiàn)的內(nèi)容!
}
-(void)myWork
{
NSLog(@"do manager's work");
}
@end
-
代理方
- 代理方可以存在多個片林,只要實現(xiàn)委托方交給的協(xié)議就可以了端盆!下面是舉例兩個代理方的代碼. 包含兩個類
- 其一 Worker_One
/*****************************************************************/
// Worker_One.h
@interface Worker_One:NSObject<JobContent>
-(void)doSomeRequiredWork;//遵循協(xié)議必須實現(xiàn)的函數(shù)
@end
// Worker_One.m
#import Worker_One.h
@implementation Worker_One
-(void)doSomeRequiredWork
{
NSLog(@"do Worker_One's Job");
}
@end
- 其二
/*****************************************************************/
// Worker_Two.h
@interface Worker_Two:NSObject<JobContent>
-(void)doSomeRequiredWork;//遵循協(xié)議必須實現(xiàn)的函數(shù)
-(void)doSomeOptionalWork;//woker two 有實現(xiàn)可選操作
@end
// Worker_Two.m
#import Worker_Two.h
@implementation Worker_Two
-(void)doSomeRequiredWork
{
NSLog(@"do Worker_Two's Job");
}
-(void)doSomeOptionalWork
{
NSLog(@"My optional work,I'm worker two");
}
@end
- 最后的綜合調(diào)用
-(void)ViewDidLoad
{
Manager* manager = [Manager new];
Worker_One *w_1 = [Worker_One new];
Worker_Two *w_2 = [Worker_Two new];
manager.delegate = w_1;
[manager doWork];
manager.delegate = w_2;
[manager doWork];
}
如果情況為 自己 委托 自己作為代理,實現(xiàn)協(xié)議函數(shù)
則無所謂在@property中設(shè)定 id<協(xié)議名> 代理方
這時候费封, 委托函數(shù)傳入的值就是self, 協(xié)議函數(shù)也在同一 .m中焕妙,
如我們的sdk里的例子
1. `- (void)initializeAudioDriver`
2. `{`
3. ` // 音頻連接參數(shù)`
4. ` id\<NLDeviceConnParams\> params = [[NLAudioPortV100ConnParams alloc] init];`
5. ` // 請求連接并獲取ME11終端設(shè)備`
6. ` NSError \*err = nil; // 驅(qū)動連接設(shè)備錯誤指針`
7. `***// ———————— 委托函數(shù) ——————————***`
8. ` self.device = [self.driver connectWithConnParams:params`
9. **` closedListener:self // 代理方:id\<某協(xié)議\>,此處委托自己`**
10. **` launchListener:self // `****`代理方:id\<某協(xié)議\>弓摘,此處委托自己`**
11. ` error:&err];`
12. ` if (err || !self.device) { // 獲取失敗`
13. ` [self performSelectorOnMainThread:@selector(onDeviceConnectFailed:) withObject:[NSString stringWithFormat:@"%@", err] waitUntilDone:NO];`
14. ` return ;`
15. ` }`
16. ` NSLog(@"Audio device instance %@", self.device);`
17. ` [self performSelectorOnMainThread:@selector(onDevicecConnectSuccess) withObject:nil waitUntilDone:NO];`
18. `}`
下面是協(xié)議函數(shù) onEvent
1. `- (void)onEvent:(id \<NLDeviceEvent\>)event`
2. `{`
3. ` NSLog(@"onEvent : %@", event);`
4. ` // TODO判別事件類型并做相應(yīng)處理`
5. ` if ([event isKindOfClass:[NLConnectionCloseEvent class]]) {`
6. ` [(UINavigationController\*)self.window.rootViewController topViewController].title = @"設(shè)備斷開連接";`
7. ` if ([self.viewController respondsToSelector:@selector(addText:)]) {`
8. ` [self.viewController performSelector:@selector(addText:) withObject:@"設(shè)備斷開連接!!!"];`
9. ` }`
10. ` `
11. ` } else if ([event isKindOfClass:[NLDeviceLaunchEvent class]]) {`
12. ` NLDeviceLaunchEvent \*launchEvent = (NLDeviceLaunchEvent\*)event;`
13. ` if ([launchEvent isSuccess]) {`
14. ` // 0xA5 + Len(2B) + 0x3A + 固件版本號(1B) + ksn + CRC(1B) + 0x5A`
15. ` NSData \*data = [launchEvent userInfo][NLDeviceLaunchDataInfo];`
16. ` if (data.length \> 7) {`
17. ` NSLog(@"KSN : %@", [NLISOUtils hexStringWithData:[data subdataWithRange:NSMakeRange(5, data.length - 7)]]);`
18. ` }`
19. ` }`
20. ` } else if ([event isKindOfClass:[NLDeviceMenuEvent class]]) {`
21. ` NLDeviceMenuEvent \*menuEvent = (NLDeviceMenuEvent\*)event;`
22. ` NSString \*text = nil;`
23. ` if ([menuEvent isSuccess]) {`
24. ` text = [NSString stringWithFormat:@"menu keycode:%d ,ecode: %@", [menuEvent keyCode], [menuEvent eCode]];`
25. ` } else {`
26. ` text = [NSString stringWithFormat:@"menu event failed!error: %@", [menuEvent error]];`
27. ` }`
28. ` [self.viewController performSelector:@selector(addText:) withObject:text];`
29. ` }`
30. `}`