成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

開發過程中該選擇Blocks還是Delegates

移動開發 iOS
有人問了我一個很棒的問題,我把這個問題總結為:“開發過程中該選擇 blocks or delegates?當我們需要實現回調的時候,使用哪一種方式比較合適呢?”......

[[150507]]

有人問了我一個很棒的問題,我把這個問題總結為:“開發過程中該選擇 blocks or delegates?當我們需要實現回調的時候,使用哪一種方式比較合適呢?”

一般在這種情況下,我喜歡問我自己:“如果問題交給Apple,他會怎么做呢?”當然,我們都知道Apple肯定知道怎么做,因為從某一層面上看,Apple的文檔就是一本用來指導我們如何使用設計模式的指導書。

因此我們需要去研究一下Apple分別是在什么情況下使用delegate和block,如果我們發現了Apple做這種選擇的套路,我們就可以構建出一些規則,可以幫助在我們在自己的代碼中做相同選擇。

要找出Apple使用delegate的場景很簡單,我們只要搜索官方文檔中的“delegate”,就會獲取到很多使用delegation的類。

但是搜索Apple中有關使用blocks的文檔就有點困難了,因為我們不能直接搜索文檔中的“^” 。然而,Apple聲明方法時有很好的命名習慣(這也是我們精通iOS開發的一項必備技能)。例如:一個以NSString為參數的方法,方法的selector就會有String字眼,像initWithString;dateFromString;StartSpeaingString。

當Apple的方法使用block,這個方法將會有“Handler”,“Completion”或者簡單的“Block”作為selector;因此我們可以在標準的iOS API文檔中搜索這些關鍵詞,用以構建一個可信任的block用例列表。

1.大多數delegate protocols 都擁有幾個消息源。

以我正在看的GKMatch為例(A GKMatch object provides a peer-to-peer network between a group of devices that are connected to Game Center,是iOS API中用來提供一組設備連接到Game Center點對點網絡的對象)。從這個類中可以看到消息的來源分別是:當從其他玩家那接收到數據、當玩家切換了狀態、當發生錯誤或者當一個玩家應該被重新邀請。這些都是不同的事件。如果Apple在這里使用block,那么可能會有以下兩種解決方式:

可以對應每一個事件注冊相應的block,顯然這種方式是不合理的。( If someone writes a class that does this in Objective-C, they are probably an asshole.)

創建一個可以接受任何可能輸入的block

1

void (^matchBlock)(GKMatchEvent eventType, Player *player, NSData *data, NSError *err);

很明顯這種方式既不簡便又不易讀,所以你可能從未看過這樣的解決方案。如果你看過這樣的解決方式,但是這顯然是一個糟糕至極的代碼行,你不會有精力去維護這個。

因此,我們可以得出一個結論:如果對象有超過一個以上不同的事件源,使用delegation。

2.一個對象只能有一個delegate

由于一個對象只能有一個delegate,而且它只能與這個delegate通信。讓我們看看CLLocationManager 這個類,當發現地理位置后,location manager 只會通知一個對象(有且只有一個)。當然,如果我們需要更多的對象去知道這個更新,我們***創建其他的location manager。

這里有的人可能想到,如果CLLocationManager是個單例呢?如果我們不能創建CLLocationManager的其他實例,就必須不斷地切換delegate指針到需要地理數據的對象上(或者創建一個只有你理解的精密的廣播系統)。因此,這樣看起來,delegatetion在單例上沒有多大意義。

關于這點,***的印證例子就是UIAccelerometer。在早期版本的iOS中,單例的 accelerometer 實例有一個delegate,導致我們必須偶爾切換一下。這個愚蠢的問題在之后的IOS版本被修改了,現在,任意一個對象都可以訪問CMMotionManager block,而不需要阻止其他的對象來接收更新。

因此,我們可以得出另一個結論:“如果一個對象是單例,不要使用delegation”。

3.一般的delegate方法會有返回值

如果你觀察一些delegate方法(幾乎所有的dataSource方法)都有一個返回值。這就意味著delegating對象在請求某些東西的state(對象的值,或者對象本身),而一個block則可以合理地包含state或者至少是推斷state,因此block真正是對象的一個屬性。

讓我們思考一下一個有趣的場景,如果向一個block提問:“What do you think about Bob?”。block可能會做兩件事情:發送一個消息去捕獲對象并詢問這個對象怎么看待Bob,或者直接返回一個捕獲的值。如果返回了一個對象的響應,我們應該越過這個block直接獲取這個對象。如果它返回了一個捕獲的值,那么這應該是一個對象的屬性。

從以上的觀察,我們可以得出結論:如果對象的請求帶有附加信息,更應該使用delegation

4.過程 vs 結果(Process vs. Results)

如果查看NSURLConnectionDelegate 以及 NSURLConnectionDataDelegate,我們在可以protocol中看到這樣的消息:我將要做什么(如: willSendRequest,將要發送請求)、到目前為止我知道的信息(如:canAuthenticateAgainstProtectionSpace)、我已經完成這些啦( didReceiveResponse,收到請求的回復,即完成請求)。這些消息組成一個流程,而那些對流程感興趣的delegate將會在每一步得到相應的通知。

當我們觀察handler和完整的方法時,我們發現一個block包含一個響應對象和一個錯誤對象。顯然這里沒有任何有關“我在哪里,我正在做什么的”的交互。

因此我們可以這樣認為,delegate的回調更多的面向過程,而block則是面向結果的。如果你需要得到一條多步進程的通知,你應該使用delegation。而當你只是希望得到你請求的信息(或者獲取信息時的錯誤提示),你應該使用block。(如果你結合之前的3個結論,你會發現delegate可以在所有事件中維持state,而多個獨立的block確不能)

從上面我們可以得出兩個關鍵點。首先,如果你使用block去請求一個可能失敗的請求,你應當只使用一個block。我們可以看到如下的代碼:
1
2
3
4
5

[fetcher makeRequest:^(id result) {
// do something with result
} error:^(NSError *err) {
// Do something with error
}];

上面代碼的可讀性明顯比下面block的可讀性差(作者說這個是他不謙虛的觀點,其實個人認為沒有那么嚴重)
1
2
3
4
5
6
7

[fetcher makeRequest:^(id result, NSError *err) {
if(!err) {
// handle result
} else {
// handle error
}
}];


 

責任編輯:chenqingxiang 來源: CocoaChina
相關推薦

2010-03-04 09:54:24

Android開發

2009-06-17 16:10:37

Java網站優勢

2011-07-06 16:00:28

ASP

2009-11-23 20:39:21

ibmdw敏捷開發

2011-01-26 09:40:42

.NET開發

2015-09-10 09:55:36

移動web開發問題

2010-07-05 12:09:10

RationalJazz需求管理

2009-06-10 15:36:25

ubuntu netb開發過程

2009-06-17 14:33:08

java項目開發

2016-12-30 11:10:32

Hadoop開發JVM

2010-06-12 15:41:28

UML建模

2011-01-04 10:05:45

敏捷開發

2010-07-15 14:47:05

Perl開發

2020-10-23 10:31:59

開發開源工具開源

2012-06-25 10:13:00

Java.NET

2024-10-29 09:20:01

2012-11-13 11:27:16

詳細設計

2022-07-31 19:59:42

文檔管理工具互聯網

2024-06-30 19:45:11

2011-04-14 15:35:53

嵌入式系統嵌入式
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 中文字幕亚洲一区二区三区 | 99爱在线观看 | 日本特黄a级高清免费大片 特黄色一级毛片 | 国产精品久久av | 夜夜精品浪潮av一区二区三区 | 91精品国产综合久久久久 | 米奇7777狠狠狠狠视频 | 成人免费黄色片 | 亚洲久在线| 蜜桃久久 | 婷婷五月色综合香五月 | 中文字幕在线精品 | 精品亚洲一区二区三区 | 久久a久久 | 国产在线一区二区 | 99久久精品国产一区二区三区 | 日韩一区精品 | 亚洲一区成人 | 国产精品久久久久久久久久免费看 | 日本免费一区二区三区四区 | 在线成人精品视频 | 九色视频网站 | 91视频网址 | 欧美一区二区视频 | 国产成人自拍一区 | 免费视频成人国产精品网站 | 国产精品视频一区二区三区不卡 | 日韩欧美一区在线 | 97精品超碰一区二区三区 | japanhdxxxx裸体| 欧美一区久久 | 欧美精品一二区 | 国产成人高清视频 | 国产目拍亚洲精品99久久精品 | 久久99精品久久久久久 | 精品成人一区二区 | 久久国产精品一区 | 国产婷婷精品 | 精品香蕉一区二区三区 | 国产精品成人一区二区三区 | 国产精品欧美日韩 |