前面的博客中提到過回調的概念,是在OC通過協議來實現的回調,和Java中的接口的回調極為相似,下面來介紹另一種方法回調模式: Target-Action回調。首先我們來從字面意思來理解一下Target-Action回調模式,Target目標即我們要調用哪個目標對象中的方法。Action是行為的意思,就是我們要調用目標對象中的哪一個方法。委托回調模式之前在Java中接觸過,而Target-Action回調模式筆者是第一次接觸,可能是筆者道行太淺,感覺這是OC中對回調的新用法,感覺還行,不難理解。
還是那句話,廢話少說,用代碼說問題最為直接了。下面代碼是筆者根據自己的理解寫的的測試demo,不足之處還請批評指正,轉載或者引用請注明出處。
在做測試的Project中,我們需要用到一個Controler和兩個組件ComponentOne和ComponentTwo。為了體現出Target-Action回調模式,我們需要在組件中通過Target-Action回調模式來回調Controler中每個組件所對應的方法。為實現在組件中的回調,我們需要Controler在組件中進行注冊,不然就找不到target對象和回調的方法啦。
為了作對比,在組件1中回調的方法是不帶參數的,而在組件2中回調的方法是帶參數的。可能到這讀者看來上面的內容感覺有點抽象,看代碼來的最為直接,代碼走起~
1.首先我們先編寫我們的組件1,在組件1中回調的Controler方法是不帶參數的
組件1中的接口:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
//
// ComponentOne.h
//
#import <Foundation/Foundation.h>
@interface ComponentOne : NSObject
//記錄target和action的屬性
@property (nonatomic, strong) id target;
@property (nonatomic, assign) SEL action;
//聲明目標動作注冊方法
-(
void
) addTarget : (id)target Action : (SEL)action;
//組件一的啟用方法
-(
void
) start;
@end
|
組件1的實現:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
//
// ComponentOne.m
//
#import "ComponentOne.h"
@implementation ComponentOne
//實現組件中的注冊方法
-(
void
)addTarget:(id)target Action:(SEL)action
{
self.target = target;
self.action = action;
}
//實現組件的啟動方法
-(
void
)start
{
//回調target對象中的action方法
[self.target performSelector:_action];
}
@end
|
代碼說明:
1.屬性target用於接收Controler的對象,也就是要回調的目標對象。
2.屬性action用於接收目標對象的方法,也就是要在目標對象中要回調的方法
3.addTarget: Action:方法用於注冊目標動作,說白了目標對象和目標對象的方法是通過這個方法傳入到組件中的
4.start函數負責回調目標對象中的方法
2.組件1完事以后我們就開始編寫我們的組件2啦,組件2和組件1中唯一不同的地方是回調的方法需要組件2提供參數,下面就只給出不同的部分代碼:
|
1
2
3
4
5
|
//組件二的啟動方法
-(
void
)start
{
[self.target performSelector:self.action withObject:@
"*組件二中返回的參數*"
];
}
|
代碼說明: 在回調Controler方法的時候,需要組件2提供參數,然后再回調
3.組件寫好了,接下來我們就開始裝配了,下面我們就開始編寫我們的Controler方法,來完成組裝任務,並且給每個組件提供相應的回調方法。在每個回調方法中就開始編寫我們的業務邏輯,同時也可以根據組件提供的參數來實現我們的特定業務邏輯。下面就是我們的Controler的實現部分。
裝配時為了隱藏我們的組件,我們在實現文件中用延展來裝配我們的組件,假定在Controler中要使用我們的組件1、2,Controler中的代碼如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
#import "Controler.h"
#import "ComponentOne.h"
#import "ComponentTwo.h"
//在Controler中使用ComponentOne組件和ComponentTow組件
//為了隱藏Controler內部組件,我們用延展進行組件的聲明和調用
@interface Controler ()
//聲明組件
@property(nonatomic, strong) ComponentOne *oneComponent;
@property(nonatomic, strong) ComponentTwo *twoComponent;
//聲明Controler中的方法,用於組件的回調
//聲明組件一中回調的方法,無慘方法
-(
void
)componentOneFunction;
//聲明組件二中的回調方法,有參方法
-(
void
)componentTwoFunction : (NSString *)strValue;
@end
//-----------------------實現部分---------------------------
@implementation Controler
//進行組件的初始化並注冊回調方法
- (instancetype)init
{
self = [super init];
if
(self) {
//給組件一分配內存空間
self.oneComponent = [[ComponentOne alloc] init];
//注冊組件一的回調方法
[self.oneComponent addTarget:self Action:@selector(componentOneFunction)];
//啟動組件一
[self.oneComponent start];
//給組件二分配內存空間
self.twoComponent = [[ComponentTwo alloc] init];
//注冊組件二的回調方法
[self.twoComponent addTarget:self Action:@selector(componentTwoFunction:)];
//啟動組件二
[self.twoComponent start];
}
return
self;
}
//實現controler中的回調方法
-(
void
)componentOneFunction
{
NSLog(@
"我是Controler中的componentOneFunction方法,我是在組件一中回調使用的"
);
}
-(
void
)componentTwoFunction:(NSString *)strValue
{
NSLog(@
"我是Controler中的componenTwoFunction方法,我的參數%@是從組件二中回調時獲取的"
, strValue);
}
@end
|
代碼說明:
1.在Controler中我們聲明並實例化了我們要使用的組件模塊
2.在Controler中聲明和實現組件中Controler對象要回調的方法
3.在組件實例化后我們要再組件中注冊我們要調用Controler中的那個方法。
4.注冊后,我們就可以啟動組件來測試組件功能
4,在mian函數中我們為了測試,把Controler進行實例化,代碼如下:
|
1
2
|
//controler的實現
Controler *controler = [[Controler alloc] init];
|
上面代碼的運行結果如下:
|
1
2
|
2014-08-18 08:33:23.900 Test2[544:303] 我是Controler中的componentOneFunction方法,我是在組件一中回調使用的
2014-08-18 08:33:23.902 Test2[544:303] 我是Controler中的componenTwoFunction方法,我的參數*組件二中返回的參數*是從組件二中回調時獲取的
|
上面所有的代碼是筆者根據個人理解Target-Action回調模式來設計的樣例,因水平有限,避免有偏頗之處。希望大家批評指正,還是那句話,如需轉載請注明出處。
