iOS之targetAction代理模式

在.h文件中添加兩個(gè)成員變量:
_target 和 _action
并且為這兩個(gè)成員聲明一個(gè)設(shè)置初值的方法:

  • (void)addMyTarget:(id)target action:(SEL)action;
    在.m文件中,當(dāng)進(jìn)去touchbegan時(shí),讓_target去執(zhí)行以下動(dòng)作:
    [_target performSelector:_action withObject:self];
    但是這個(gè)時(shí)候, _target是什么?_action是什么?

代理和targetAction的異同:

相同:首先他們都是讓controller來做一些事情.我們要明白一點(diǎn):我們舉的例子是觸摸事件發(fā)生的.但實(shí)際上這是view想要做什么事情的時(shí)候, 將邏輯部分交給controller來做的一種手段. 就算不是觸摸事件,一樣可以讓代理或者addtargetaction來做這些事情哦.
不同:實(shí)現(xiàn)方法不一樣,說不清楚,看例子吧:

targetAction: 代理:
1.創(chuàng)建RootViewController和RootView 代理相對(duì)來說就比較簡(jiǎn)單了, 你只需要明白代理是怎么回事就行了
2.現(xiàn)在我有一個(gè)視圖view的一些行為需要讓RootViewController來做,為了模擬這個(gè)主體,我再創(chuàng)建一個(gè)TouchView的視圖.處理這視圖的所有行為都放到RootViewController來做. 簡(jiǎn)單的說,你會(huì)描述,你就會(huì)寫.
3.在TouchView.h中做如下的事情:
3.1)添加兩個(gè)成員變量:
id _target; //目標(biāo). 讓誰來做這些事兒.
SEL _action; //實(shí)現(xiàn). 誰去實(shí)現(xiàn)這個(gè)方法.
3.2)為這兩個(gè)成員變量添加設(shè)置方法:
- (void)addMyTarget:(id)target action:(SEL)action;"
誰是委托人?誰是代理?委托人需要什么功能?代理需要能提供什么功能?
4.在TouchView.m中的Touch..began事件處理方法中,添加這樣一行代碼:
[_target performSelector:_action withObject:self];
解釋一下:通俗的講:就是讓_target去做_action這個(gè)動(dòng)作.
深層次一點(diǎn)的說法是,_target是一個(gè)對(duì)象的主體,_target賦值后的對(duì)象一定有執(zhí)行方法的能力.那么,首先,賦的值必須是一個(gè)對(duì)象.誰給_target賦值,誰就負(fù)責(zé)傳一個(gè)對(duì)象過來.但是你代碼寫在這里,誰能給你賦值?誰知道你在誰?怎么給你值?
perform是一個(gè)登記的機(jī)制, 我猜啊, 有一張方法字典表, 記錄了selector可以查找到的所有方法.當(dāng)然我這么說一點(diǎn)根據(jù)都沒有,我在瞎猜.先往下寫一點(diǎn),沒準(zhǔn)就明白了." 委托者是:TouchView 代理是RootViewController.
5.如果我們點(diǎn)擊了屏幕發(fā)生了事件(點(diǎn)在了TouchView中),那么會(huì)發(fā)生什么事情?
根據(jù)響應(yīng)者鏈規(guī)則1,我們找到了TouchView,發(fā)現(xiàn)TouchView中有處理方法(touch began).于是它就執(zhí)行了[_target performSelector:_action withObject:self];這段代碼….我靠,有controller毛事兒啊!
媽蛋,這performSelector肯定做了什么事情!" 委托人負(fù)責(zé)制定協(xié)議, 代理需要引入委托人的頭文件(引入類和協(xié)議)
這里簡(jiǎn)直就是一個(gè)深坑. 委托人需要自己調(diào)方法, 但是這個(gè)方法是代理提供的.
SEL:是一種數(shù)據(jù)類型,它對(duì)方法進(jìn)行了包裝(說的好聽),上面的_action的類型是SEL,也就是:@selector(fun)類型. 真正執(zhí)行方法的時(shí)候,實(shí)在委托人的方法中,(在委托人的方法中),給代理發(fā)送了一個(gè)代理的方法, 轉(zhuǎn)而代理去執(zhí)行了那個(gè)方法.
SEL是一個(gè)結(jié)構(gòu)體,它是對(duì)方法封裝后得到的,所以,里面不單單應(yīng)該有函數(shù)指針. 所以,這兩種模式,都使用到了一ID類型.通用類型指針.
我明白了!關(guān)鍵是:包裝的SEL類型數(shù)據(jù)它對(duì)應(yīng)相應(yīng)的方法地址,找到方法地址就可以調(diào)用方法 targetaction的id是作為一個(gè)替換的變量存在的.而委托人中的id<協(xié)議>類型指針,則是實(shí)實(shí)在在的指向了一個(gè)對(duì)象
"從整個(gè)ios的app流程來說,先走完RootViewController的Viewdidload方法, 那之前已經(jīng)實(shí)例化了一個(gè)TouchView的對(duì)象.里面已經(jīng)對(duì)這兩個(gè)_target和_action賦值了.另外,TouchView已經(jīng)是一個(gè)對(duì)象了,它當(dāng)然能調(diào)用方法.所以,當(dāng)發(fā)生點(diǎn)擊事件的時(shí)候,_tar和_action都已經(jīng)可以直接調(diào)用了.
在touchbegan方法中,[_target performSelector:_action withObject:self];變成了:
[RootViewController performSelector:@selector(touchViewAction:) withObject:TouchView];
這段代碼在哪兒執(zhí)行的呢?實(shí)在TouchView.m中的touchbegan中." id是所有對(duì)象類型的父指針,父類指針指向子類對(duì)象,這其實(shí)是一種多態(tài)現(xiàn)象.
"整個(gè)過程有點(diǎn)如下的意思:
我是TouchView類,我一會(huì)兒要接受觸摸事件,做出一個(gè)動(dòng)作, 我做動(dòng)作的格式是
[_target performSelector:_action withObject:self];
你們一會(huì)兒誰初始化我,實(shí)例化我的對(duì)象的時(shí)候, 一定要把_target和_action給我賦上值啊.到時(shí)候我根據(jù)你們的賦值,去你們的對(duì)象里找方法." "于是乎:委托人需要提供:
1)協(xié)議(用到了class),
2)委托人需要提供一個(gè)id類型的通用指針,用來指向代理(具體的對(duì)象)可以通過指向不同的代理,用相同的調(diào)用代碼執(zhí)行處不同的結(jié)果(這tm的就是多態(tài)啊).
3)調(diào)用代碼([self.delegate 方法],方法名相同但是因?yàn)閐elegate指向不同的對(duì)象,而每個(gè)對(duì)象都遵循實(shí)現(xiàn)這個(gè)方法的協(xié)議,所以他們能得到不同的結(jié)果, 在這里,只是一種結(jié)果, 是對(duì)代理協(xié)議模式的一種應(yīng)用,一種閹割的應(yīng)用方法."
相反, 代理 虱子多了不癢, 我只需要顯示的將子視圖的代理指針(id類型)指向自己,然后給你提供一個(gè)方法,就不管你了, 你什么時(shí)候需要執(zhí)行我的代碼,隨便來. 反正我也不會(huì)被你中斷.放馬過來..
在TouchView.h中

@interface TouchView : UIView   
{   
    // 這兩個(gè)東西可以幫我們拆離代碼   
    // 第一步: 
    id _target; //目標(biāo). 讓誰來做這些事兒. 
    SEL _action; //實(shí)現(xiàn). 誰去實(shí)現(xiàn)這個(gè)方法.    
}   
    
// 提供一個(gè)借口,添加目標(biāo)和行動(dòng).  
// 第二步: 
- (void)addMyTarget:(id)target action:(SEL)action;  
    
@end    
    
在TouchView.m中   
@implementation TouchView   
    
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{   
    // 第三步: 
    [_target performSelector:_action withObject:self];  
}   
    
- (void)addMyTarget:(id)target action:(SEL)action   
{   
    _target = target;   
    _action = action;   
}   
    
@end    
    
在RootViewController中:先實(shí)例化對(duì)象 ,再報(bào)備(為_target和_action賦值, 最后是action方法.   
-(void)loadView 
{   
    self.rv = [[[RootView alloc] initWithFrame:[UIScreen mainScreen].bounds]autorelease];   
    self.view = _rv;    
}   
    
- (void)viewDidLoad {   
    [super viewDidLoad];    
    
    // 報(bào)備.  
    [self.rv.tv addMyTarget:self action:@selector(touchViewAction:)];   
    //self.rv.backgroundColor = [UIColor greenColor];   
}   
    
- (void)touchViewAction:(TouchView *)sender 
{   
    NSLog(@"%@",sender); // 如果performselector不傳第二個(gè)參數(shù)withobject,那么這里的sender就不能用. 
    sender.backgroundColor =[UIColor colorWithRed:arc4random()%256/255.0 \  
                                          green:arc4random()%256/255.0 \    
                                           blue:arc4random()%256/255.0 \    
                                          alpha:1];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.OC里用到集合類是什么? 基本類型為:NSArray,NSSet以及NSDictionary 可變類型為:NS...
    輕皺眉頭淺憂思閱讀 1,483評(píng)論 0 3
  • 循環(huán)引用:http://ios.jobbole.com/82077/類別的作用功能:1.擴(kuò)充現(xiàn)有類的功能2.對(duì)現(xiàn)有...
    得一切從簡(jiǎn)閱讀 586評(píng)論 0 1
  • 面向?qū)ο笕笾е庋b:就是把相關(guān)的數(shù)據(jù)和代碼結(jié)合成一個(gè)有機(jī)的整體,形成數(shù)據(jù)和操作代碼的封裝體,對(duì)外只提供一個(gè)可以控...
    WangDavid閱讀 1,973評(píng)論 0 2
  • 文/你的彼得兔 “好,我知道了。我現(xiàn)在特別忙,你能不能幫我跟那邊先對(duì)接一下。這個(gè)項(xiàng)目對(duì)我們非常重要,所以你努力幫我...
    桃心姑娘閱讀 1,236評(píng)論 22 10
  • 過年了, 他帶著她, 一起去拜年。 朋友家、同事家、領(lǐng)導(dǎo)家, 每到一處, 他都會(huì)喝酒, 有時(shí)她也喝, 但大多數(shù)時(shí)候...
    聽瑛語閱讀 165評(píng)論 0 1

友情鏈接更多精彩內(nèi)容