Block很簡(jiǎn)單,就像delegate的簡(jiǎn)化版

摘要

block的語(yǔ)法讓人很蛋疼谆级,但是如果好好理一下思路讼积,發(fā)現(xiàn)也沒(méi)那么難。

代理設(shè)計(jì)模式對(duì)于iOS開(kāi)發(fā)的人來(lái)說(shuō)肯定很熟悉了勤众,代理delegate就是委托另一個(gè)對(duì)象來(lái)幫忙完成一件事情,為什么要委托別人來(lái)做呢吕朵,這其實(shí)是MVC設(shè)計(jì)模式中的模塊分工問(wèn)題窥突,例如View對(duì)象它只負(fù)責(zé)顯示界面,而不需要進(jìn)行數(shù)據(jù)的管理梧税,數(shù)據(jù)的管理和邏輯是Controller的責(zé)任,所以此時(shí)View就應(yīng)該將這個(gè)功能委托給Controller去實(shí)現(xiàn)第队,當(dāng)然你作為碼農(nóng)強(qiáng)行讓View處理數(shù)據(jù)邏輯的任務(wù)煌茬,也不是不行,只是這就違背了MVC設(shè)計(jì)模式晾蜘,項(xiàng)目小還好,隨著功能的擴(kuò)展剔交,我們就會(huì)發(fā)現(xiàn)越寫越難寫;還有一種情況岖常,就是這件事情做不到,只能委托給其他對(duì)象來(lái)做了板惑,下面的例子中我會(huì)說(shuō)明這種情況偎快。

下面的代碼我想實(shí)現(xiàn)一個(gè)簡(jiǎn)單的功能,場(chǎng)景描述如下:TableView上面有多個(gè)CustomTableViewCell裆馒,cell上面顯示的是文字信息和一個(gè)詳情Button丐怯,點(diǎn)擊button以后push到一個(gè)新的頁(yè)面。為什么說(shuō)這個(gè)場(chǎng)景用到了代理delegate读跷?因?yàn)閎utton是在自定義的CustomTableViewCell上面,而cell沒(méi)有能力實(shí)現(xiàn)push的功能些膨,因?yàn)閜ush到新頁(yè)面的代碼是這樣的钦铺,

[self.navigationController pushViewController...];

所以這時(shí)候CustomTableViewCell就要委托它所在的Controller去做這件事情了肢预。

按照我的編碼習(xí)慣,我喜歡把委托的協(xié)議寫在提出委托申請(qǐng)的類的頭文件里面烫映,現(xiàn)在的場(chǎng)景中是CustomTableViewCell提出了委托申請(qǐng),下面是簡(jiǎn)單的代碼抽兆,

@protocolCustomCellDelegate

- (void)pushToNewPage;

@end

@interfaceCustomTableViewCell :UITableViewCell

@property(nonatomic,assign)iddelegate;

@property(nonatomic,strong)UILabel *text1Label;

@property(nonatomic,strong) UIButton *detailBtn;

@end

上面的代碼在CustomTableViewCell.h中定義了一個(gè)協(xié)議CustomCellDelegate族淮,它有一個(gè)需要實(shí)現(xiàn)的pushToNewPage方法凭涂,然后還要寫一個(gè)屬性修飾符為assign切油、名為delegate的property名惩,之所以使用assign是因?yàn)檫@涉及到內(nèi)存管理的東西,以后的博客中我會(huì)專門說(shuō)明原因娩鹉。

接下來(lái)在CustomTableViewCell.m中編寫B(tài)utton點(diǎn)擊代碼,

[self.detailBtnaddTarget:selfaction:@selector(btnClicked:)forControlEvents:UIControlEventTouchUpInside];

對(duì)應(yīng)的btnClicked方法如下巢株,

- (void)btnClicked:(UIButton*)btn

{

if(self.delegate&& [self.delegaterespondsToSelector:@selector(pushToNewPage)]) {

[self.delegatepushToNewPage];

}

}

上面代碼中的判斷條件最好是寫上熙涤,因?yàn)檫@是判斷self.delegate是否為空,以及實(shí)現(xiàn)CustomCellDelegate協(xié)議的Controller是否也實(shí)現(xiàn)了其中的pushToNewPage方法那槽。

接下來(lái)就是受到委托申請(qǐng)的類,這里是對(duì)應(yīng)CustomTableViewCell所在的ViewController骚灸,它首先要實(shí)現(xiàn)CustomCellDelegate協(xié)議慌植,然后要實(shí)現(xiàn)其中的pushToNewPage方法,還有一點(diǎn)不能忘記的就是要設(shè)置CustomTableViewCell對(duì)象cell的delegate等于self丈钙,很多情況下可能忘了寫cell.delegate = self;導(dǎo)致遇到問(wèn)題不知云里霧里交汤。下面的關(guān)鍵代碼都是在ViewController.m中,

首先是服從CumtomCellDelegate協(xié)議芙扎,這個(gè)大家肯定都知道,就像很多系統(tǒng)的協(xié)議俏橘,例如UIAlertViewDelegate、UITextFieldDelegate寥掐、UITableViewDelegate、UITableViewDatasource一樣曹仗。

@interfaceViewController()

@property(nonatomic,strong) NSArray *textArray;

@end

然后是實(shí)現(xiàn)CustomCellDelegate協(xié)議中的pushToNewPage方法,

- (void)pushToNewPage

{

DetailViewController*detailVC = [[DetailViewControlleralloc] init];

[self.navigationControllerpushViewController:detailVCanimated:YES];

}

還有一個(gè)步驟最容易被忘記收壕,就是設(shè)置CumtomTableViewCell對(duì)象cell的delegate轨蛤,如下代碼,

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

staticNSString*simpleIdentify =@"CustomCellIdentify";

CustomTableViewCell*cell = [tableViewdequeueReusableCellWithIdentifier:simpleIdentify];

if(cell ==nil) {

cell = [[CustomTableViewCellalloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:simpleIdentify];

}

//下面代碼很關(guān)鍵

cell.delegate=self;

cell.text1Label.text= [self.textArrayobjectAtIndex:indexPath.row];

returncell;

}

通過(guò)cell.delegate = self;確保了CustomTableViewCell.m的判斷語(yǔ)句if(self.delegate && ...){}中得self.delegate不為空圃验,此時(shí)的self.delegate其實(shí)就是ViewController缝呕,cell對(duì)象委托了ViewController實(shí)現(xiàn)pushToNewPage方法。這個(gè)簡(jiǎn)單的場(chǎng)景描述了使用代理的一種情況供常,就是CustomTableViewCell沒(méi)有能力實(shí)現(xiàn)pushViewController的功能,所以委托ViewController來(lái)實(shí)現(xiàn)麻裁。

代碼在github可以下載源祈。

有什么錯(cuò)誤,還請(qǐng)大家指正香缺。

----------------------------------------------下面是block的內(nèi)容----------------------------------------------------

Block是一個(gè)C語(yǔ)言的特性,就像群里有人說(shuō)的原献,它就是C語(yǔ)言的函數(shù)指針埂淮,在使用中最多的就是進(jìn)行函數(shù)回調(diào)或者事件傳遞,比如發(fā)送數(shù)據(jù)到服務(wù)器倔撞,等待服務(wù)器反饋是成功還是失敗慕趴,此時(shí)block就派上用場(chǎng)了鄙陡,這個(gè)功能的實(shí)現(xiàn)也可用使用代理躏啰,這么說(shuō)的話,感覺(jué)block是不是有點(diǎn)像代理了呢毫捣?

我之前接觸block,都是使用它作為函數(shù)參數(shù)蔓同,當(dāng)時(shí)感覺(jué)不是很理解《拙鳎現(xiàn)在在項(xiàng)目中,很多時(shí)候block作為property脯爪,這樣更加簡(jiǎn)單直接,想想咒锻,其實(shí)property不就是定義的合成存儲(chǔ)的變量嘛守屉,而block作為函數(shù)參數(shù)也是定義的變量,所以作為函數(shù)參數(shù)或者作為property本質(zhì)沒(méi)有區(qū)別拇泛。

看一看別人總結(jié)的block的語(yǔ)法吧,http://fuckingblocksyntax.com恭取,這個(gè)鏈接亮了熄守,fucking block syntax,操蛋的block語(yǔ)法啊裕照。block有如下幾種使用情況,

1惠猿、作為一個(gè)本地變量(local variable)

returnType(^blockName)(parameterTypes) = ^returnType(parameters) {...};

2、作為@property

@property (nonatomic, copy)returnType(^blockName)(parameterTypes);

3偶妖、作為方法的參數(shù)(method parameter)

- (void)someMethodThatTakesABlock:(returnType(^)(parameterTypes))blockName;

4、作為方法參數(shù)的時(shí)候被調(diào)用

[someObject someMethodThatTakesABlock: ^returnType(parameters) {...}];

5趾访、使用typedef來(lái)定義block,可以事半功倍

typedefreturnType(^TypeName)(parameterTypes);

TypeNameblockName = ^returnType(parameters) {...};

上面我也只是復(fù)制粘貼了一下屿聋,接下來(lái)還是實(shí)現(xiàn)點(diǎn)擊CustomTableViewCell上面的Button實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)的功能,我之前不止一次的類比block就像delegate润讥,這邊我也是思維慣性盘寡,下面的內(nèi)容我就當(dāng)block為代理,一些用詞描述還是跟delegate差不多脆粥。首先,在提出委托申請(qǐng)的CustomTableViewCell中定義block的property变隔,

@interfaceCustomTableViewCell :UITableViewCell

@property(nonatomic,strong)UILabel*text1Label;

@property(nonatomic,strong)UIButton*detailBtn;

//下面的定義蟹倾,請(qǐng)看官們對(duì)比一下

/*delegate的定義 我沒(méi)有刪除,因?yàn)榇蠹铱梢灶惐攘丝聪?/

@property(nonatomic,assign)id delegate;

/*這里定義了ButtonBlock*/

@property(nonatomic,copy)void(^ButtonBlock)();

@end

這里用copy屬性來(lái)修飾ButtonBlock property肌厨,這個(gè)原因,我會(huì)在以后的博客中作專門的解釋柑爸。

接下來(lái)在CustomTableViewCell中給它上面的detailBtn綁定點(diǎn)擊方法盒音,

[self.detailBtnaddTarget:selfaction:@selector(btnClicked:)forControlEvents:UIControlEventTouchUpInside];

然后是btnClicked方法的細(xì)節(jié),我把delegate的內(nèi)容也沒(méi)有刪除譬圣,就是給各位比較一下block和delegate的功能和語(yǔ)法的相似性,

- (void)btnClicked:(UIButton*)btn

{

//這是之前的delegate

if(self.delegate&& [self.delegaterespondsToSelector:@selector(pushToNewPage)]) {

[self.delegatepushToNewPage];

}

//這是現(xiàn)在我們要說(shuō)的block

if(ButtonBlock) {

ButtonBlock();

}

}

下面是一個(gè)關(guān)鍵性的地方胁镐,在ViewController2中設(shè)置其CustomTableViewCell的cell對(duì)象的ButtonBlock诸衔,也就是給它賦值,此處我還是保留了cell.delegate = self;代碼就缆,

- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath

{

NSString*blockIdentify =@"BlockIdentify";

CustomTableViewCell*cell = [tableViewdequeueReusableCellWithIdentifier:blockIdentify];

if(cell ==nil) {

cell = [[CustomTableViewCellalloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:blockIdentify];

}

cell.text1Label.text= [self.textArrayobjectAtIndex:indexPath.row];

//delegate的不可缺少的代碼谒亦,這里放在這兒只是為了給各位類比一下

cell.delegate=self;

//ButtonBlock不可缺少的代碼

cell.ButtonBlock = ^{

[selfpushToNewPage2];

};

returncell;

}

之所以cell.ButtonBlock = ^{};賦值,是因?yàn)槲覀兾覀兪沁@樣定義ButtonBlock的份招,void (^ButtonBLock)(),表示無(wú)返回值無(wú)參數(shù)廓旬。

然后編寫pushToNewPage2方法,

- (void)pushToNewPage2

{

DetailViewController*detailVC = [[DetailViewControlleralloc]init];

[self.navigationControllerpushViewController:detailVCanimated:YES];

}

你們看這個(gè)方法是不是與CustomCellDelegate協(xié)議中的pushToNewPage方法類似孕豹。然后在回過(guò)頭來(lái)類比一樣十气,是不是block就是精簡(jiǎn)版的delegate,因?yàn)閐elegate設(shè)計(jì)模式要寫協(xié)議CustomCellDelegate叶眉,還有容易遺漏cell.delegate = self;但是block使用的時(shí)候就簡(jiǎn)單多了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末竟闪,一起剝皮案震驚了整個(gè)濱河市杖狼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌理朋,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嗽上,死亡現(xiàn)場(chǎng)離奇詭異熄攘,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)浅萧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)吩案,“玉大人,你說(shuō)我怎么就攤上這事帝簇。” “怎么了残揉?”我有些...
    開(kāi)封第一講書人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵芋浮,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我途样,道長(zhǎng),這世上最難降的妖魔是什么何暇? 我笑而不...
    開(kāi)封第一講書人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任裆站,我火速辦了婚禮,結(jié)果婚禮上宏胯,老公的妹妹穿的比我還像新娘。我一直安慰自己肩袍,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布魂爪。 她就那樣靜靜地躺著艰管,像睡著了一般。 火紅的嫁衣襯著肌膚如雪牲芋。 梳的紋絲不亂的頭發(fā)上捺球,一...
    開(kāi)封第一講書人閱讀 50,096評(píng)論 1 291
  • 那天氮兵,我揣著相機(jī)與錄音,去河邊找鬼胆剧。 笑死醉冤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蚁阳。 我是一名探鬼主播,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼螺捐,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了定血?” 一聲冷哼從身側(cè)響起诞外,我...
    開(kāi)封第一講書人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎茫虽,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體濒析,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡啥纸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盾致。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片名船。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖渠驼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤爽哎,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布器一,位于F島的核電站,受9級(jí)特大地震影響祈秕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜志鞍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一方仿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧仙蚜,春花似錦、人聲如沸委粉。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至氮双,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間送爸,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工袭厂, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留球匕,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓亮曹,卻偏偏與公主長(zhǎng)得像秘症,于是被迫代替她去往敵國(guó)和親式矫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容