Block的嵌套使用

前言

唐巧的技術(shù)博客里面有篇談Objective-C Block的實(shí)現(xiàn)的文章,對(duì)于block的內(nèi)部數(shù)據(jù)結(jié)構(gòu)、三種類(lèi)型以及相關(guān)的內(nèi)存管理方式說(shuō)的比較詳細(xì),關(guān)于這些內(nèi)容我就不在這畫(huà)蛇添足了,我主要要說(shuō)的是block的嵌套使用。在說(shuō)這個(gè)之前,推薦大家一個(gè)有意思的Objective-C Blocks Quiz,也許做完這五個(gè)小題目,你對(duì)自己掌握block的程度會(huì)有一個(gè)更客觀的認(rèn)識(shí)。

block為什么嵌套

用過(guò)WebViewJavascriptBridge進(jìn)行Objective-C和JS的交互的朋友對(duì)于下面這段代碼肯定特別熟悉:

[WebViewJavascriptBridge bridgeForWebView:webView handler:^(id data, WVJBResponseCallback responseCallback) {
    NSLog(@"Received message from javascript: %@", data);
    if (responseCallback) {
        responseCallback(@"Right back atcha");
    }
}]

如果WVJBResponseCallback換成任何一個(gè)咱們熟悉的類(lèi),那么這種模式就是咱們?cè)偈煜げ贿^(guò)的一種回調(diào)方法,但是通過(guò)看源文件,如下:

typedef void (^WVJBResponseCallback)(id responseData);
typedef void (^WVJBHandler)(id data, WVJBResponseCallback responseCallback);

可以看出WVJBResponseCallback也是一個(gè)block,第一個(gè)參數(shù)data,咱們很容易理解,傳值方式的一種,可是第二個(gè)參數(shù)是一個(gè)block,是不是感覺(jué)不太常見(jiàn)呢?別著急,這就是我今天要講的。

講之前咱們先思考一個(gè)問(wèn)題。假設(shè)有兩個(gè)類(lèi),類(lèi)A和類(lèi)B。類(lèi)A要讓類(lèi)B干一些事,類(lèi)B干完之后得反饋給類(lèi)A,類(lèi)A收到類(lèi)B的反饋信息之后需要進(jìn)行一些處理,然后還得再反饋一些信息給類(lèi)B,類(lèi)B收到類(lèi)A的反饋信息之后還要進(jìn)行一些處理。

碰到這個(gè)問(wèn)題,你會(huì)怎么處理呢?代理、通知等等,要實(shí)現(xiàn)這個(gè)問(wèn)題都不難,但是個(gè)人認(rèn)為用的最舒服的還是block。用block嵌套解決這個(gè)問(wèn)題,就顯得尤為簡(jiǎn)單。

block怎么嵌套

為了顯示這個(gè)問(wèn)題,我們先建一個(gè)KFABlockTestB類(lèi),在KFABlockTestB.h先定義兩個(gè)block,如下:

typedef void(^Ablock)(id testData);
typedef void(^Bblock)(id data, Ablock testBlock);

然后給這個(gè)類(lèi)添加一個(gè)Bblock的屬性,并添加一個(gè)實(shí)例方法,如下:

@interface KFABlockTestB : NSObject

@property (nonatomic, copy) Bblock byBlock;

- (void)testActionWith:(Bblock)block;

@end

然后在KFABlockTestB.m文件里實(shí)現(xiàn)這個(gè)方法:

- (void)testActionWith:(Bblock)block
{
    _byBlock = block;
    
    NSString *striData = @"BlockTestB say hello to VC";
    _byBlock(striData, ^(id testData){
        NSLog(@"BlockTestB get response from VC: %@",testData);
    });
}

在這里,striData就是我要反饋回去的信息,那個(gè)打印動(dòng)作就是受到調(diào)用這個(gè)方法所在的類(lèi)再次返回回來(lái)信息時(shí)進(jìn)行的處理動(dòng)作。然后在ViewController里引入KFABlockTestB.h,并定義一個(gè)屬性,如下:

#import "ViewController.h"
#import "KFABlockTestB.h"

@interface ViewController ()

@property KFABlockTestB *blockTestB;

@end

在viewDidLoad里對(duì)blockTestB進(jìn)行初始化,并調(diào)用KFABlockTestB的實(shí)例方法testActionWith:,并在回調(diào)方法block里對(duì)傳入的值進(jìn)行打印,如下:

_blockTestB = [KFABlockTestB new];
    
[_blockTestB testActionWith:^(id data, Ablock testBlock) {
   NSLog(@"Get message from blockTestB: %@",data);
   if (testBlock) {
       testBlock(@"Response for message from VC");
   }
}];

通過(guò)運(yùn)行,我們會(huì)發(fā)現(xiàn)控制臺(tái)輸出結(jié)果如下:

2015-12-17 02:17:27.518 KFABlockDemo[40010:2703474] Get message from blockTestB: BlockTestB say hello to VC
2015-12-17 02:17:27.518 KFABlockDemo[40010:2703474] BlockTestB get response from VC: Response for message from VC

這是為啥呢?因?yàn)閎lock實(shí)際上是一個(gè)對(duì)象,通過(guò)看它的內(nèi)部結(jié)果,我們發(fā)現(xiàn)它也有isa指針,所以block本身也可以作為一個(gè)參數(shù)進(jìn)行傳值。在這個(gè)demo里,KFABlockTestB在執(zhí)行testActionWith:這個(gè)方法的時(shí)候,通過(guò)回調(diào)方法相當(dāng)于進(jìn)行了一次兩個(gè)數(shù)據(jù)的傳值。一個(gè)是

data = @"BlockTestB say hello to VC"

一個(gè)是

testBlock = ^(id testData){
        NSLog(@"BlockTestB get response from VC: %@",testData);
    })

這樣再去看viewController在block回調(diào)里的動(dòng)作和控制臺(tái)的輸出結(jié)果就一目了然了。

總結(jié)

block說(shuō)難并不難,現(xiàn)在相關(guān)的資料很多,只要我們靜下心來(lái)好好看看它的實(shí)現(xiàn)原理,并多加練習(xí),就會(huì)比較熟練。但是block也沒(méi)有咱們想的那么簡(jiǎn)單,比如作為屬性時(shí)的修飾詞、傳值的內(nèi)存管理等等,得多下功夫、多費(fèi)心才能真正掌握。如果還有其他問(wèn)題或者建議,請(qǐng)通過(guò)微博或者郵件聯(lián)系我,也可以直接在評(píng)論區(qū)提出。

本文原創(chuàng),如果喜歡或者對(duì)你有用,在轉(zhuǎn)載和引用時(shí)請(qǐng)標(biāo)明出處。

參考鏈接

最后編輯于
?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,995評(píng)論 25 709
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,219評(píng)論 4 61
  • 在“跳票”了近一個(gè)月后,周鴻祎的奇酷旗艦版手機(jī)姍姍來(lái)遲,與大家見(jiàn)面了。聯(lián)想起奇酷旗艦版發(fā)布前幾天周鴻祎箭射蘋(píng)果、小...
    f11015f29d83閱讀 330評(píng)論 0 1
  • 對(duì)于世間的種種學(xué)問(wèn), 一點(diǎn)不了解也不行。 但最關(guān)鍵的是, 務(wù)必要想方設(shè)法獲得解脫, 否則, 將短暫的人生都耗在無(wú)意...
    曾路閱讀 256評(píng)論 0 0
  • 很少用button一次別的童鞋在form中用到button,發(fā)現(xiàn)每次點(diǎn)擊之后頁(yè)面會(huì)刷新。 那么button的本義和...
    清水蘆葦閱讀 917評(píng)論 0 0

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