設(shè)計(jì)模式中的迭代器模式在Cocoa Touch框架中的使用
基本理解
迭代器模式(Iterrator):提供一個(gè)方法順序訪問一個(gè)聚合對(duì)象中的各個(gè)元素,而又不暴露該元素的內(nèi)部表示。
當(dāng)你訪問一個(gè)聚合對(duì)象,而且不管這些對(duì)象是什么都需要遍歷的時(shí)候,你就應(yīng)該考慮用迭代器模式。
你需要對(duì)聚集有多種方式遍歷時(shí),可以考慮用迭代器模式。
迭代器模式就是分離了集合對(duì)象的遍歷行為,抽象出一個(gè)迭代器類來(lái)負(fù)責(zé),這樣既可以做到不暴露集合的內(nèi)部結(jié)構(gòu),又可讓外部代碼透明地訪問集合內(nèi)部的數(shù)據(jù)。
迭代器定義了一個(gè)用于訪問集合元素并記錄當(dāng)前元素的接口。
不同的迭代器可以執(zhí)行不同的迭代策略。
外部迭代器和內(nèi)部迭代器:
外部迭代器
- 外部迭代器讓客戶端直接操作迭代過程,所以客戶端需要知道外部迭代器才能使用。但是它為客戶端提供了更多的控制
- 客戶端創(chuàng)建并維護(hù)外部迭代器
- 客戶端可以使用不同外部迭代器實(shí)現(xiàn)多種類型的遍歷
內(nèi)部迭代器
- 客戶端不需要知道任何外部迭代器,而是可以通過集合對(duì)象的特殊接口,或者一次訪問一個(gè)元素,或者向集合中的每個(gè)元素發(fā)送消息。
- 集合對(duì)象本身創(chuàng)建并維護(hù)它的外部迭代器
- 集合對(duì)象可以在不修改客戶端代碼的情況下,選擇不同的外部迭代器
在Cocoa Touch框架中使用迭代器模式?
基礎(chǔ)框架中的NSEnumerator類實(shí)現(xiàn)了迭代器模式。抽象NSEnumerator類的私有具體子類返回枚舉器對(duì)象,能夠順序遍歷各種集合——數(shù)組、集合、字典,把集合中的對(duì)象返回給客戶端。
NSDirectoryEnumerator,這個(gè)類的實(shí)例遞歸枚舉文件系統(tǒng)中一個(gè)目錄的內(nèi)容。NSArray、NSSet、NSDictionary這樣的集合類,定義了返回與集合類型相應(yīng)的NSEnumerator子類實(shí)例的方法。所有的枚舉器都以同樣的方式工作,可以在一個(gè)循環(huán)中向枚舉器發(fā)送nextObject消息,從枚舉器取得對(duì)象,直到它返回nil表示遍歷結(jié)束。
1.NSEnumerator
我們可以使用NSEnumerator來(lái)枚舉NSArray、NSDictionary和NSSet對(duì)象中的元素。NSEnumerator本身是個(gè)抽象類,它有依靠幾個(gè)工廠方法,如objectEnumrator或keyEnumerator,來(lái)創(chuàng)建并返回相應(yīng)的具體枚舉器對(duì)象。代碼如下:
NSArray *array = @[@"張三", @"李四", @"王五"];
NSEnumerator *itemEnumerator = [array objectEnumerator];
NSString *item;
while (item = [itemEnumerator nextObject]) {
NSLog(@"item is :%@", item);
}
2015-08-28 16:48:05.463 NSEnumatroDemo[55301:3712762] item is :張三 2015-08-28 16:48:05.463 NSEnumatroDemo[55301:3712762] item is :李四 2015-08-28 16:48:05.464 NSEnumatroDemo[55301:3712762] item is :王五
使用NSEnumerator對(duì)數(shù)組進(jìn)行遍歷,當(dāng)消息調(diào)用[itemEnumerator nextObject]會(huì)返回nil,然后枚舉過程就結(jié)束了。
2.基于塊的枚舉
從iOS4.0后,在NSArray、NSDictionary和NSSet對(duì)象中引入了新方法,用于基于塊的枚舉。其中一個(gè)方法叫enumerateObjectsUsingBlock:(void(^)(id obj, NSUInteger idx, BOOL *stop))block。我們可以把自己的算法定義在內(nèi)嵌到消息調(diào)用之中的塊里,或者在別的什么地方預(yù)定義一個(gè)塊,然后作為參數(shù)傳給消息調(diào)用。如下代碼:
NSArray *array = @[@"張三", @"李四", @"王五"];
NSString *str = @"李四";
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(@"item is :%@", obj);
if ([obj localizedStandardCompare:str] == NSOrderedSame) {
*stop = YES;
NSLog(@"停止遍歷");
}
}];
2015-08-28 17:10:03.556 NSEnumatroDemo[55478:3723216] item is :張三 2015-08-28 17:10:03.557 NSEnumatroDemo[55478:3723216] item is :李四 2015-08-28 17:10:03.557 NSEnumatroDemo[55478:3723216] 停止遍歷
如果array數(shù)組中有字符串"李四",那么久把指針*stop設(shè)置為YES,以通知array對(duì)象提前停止遍歷。
NSSet對(duì)象中基于塊的枚舉與NSArray中的非常類似,只是在塊的參數(shù)中沒有idx參數(shù)。因?yàn)榧现械脑厥菬o(wú)序的。
使用NSArray、NSDictionary和NSSet的內(nèi)部迭代器的一個(gè)重要好處是,處理其內(nèi)容的算法可以在其他地方由其他開發(fā)人員來(lái)定義。與傳統(tǒng)的for循環(huán)中定義的算法不同,定義清晰的塊可以被復(fù)用。當(dāng)塊逐漸變大時(shí),可把它們放到單獨(dú)的實(shí)現(xiàn)文件中,不跟其他代碼擠在一起。
3.快速枚舉
從iOS2.0后提供了一種枚舉,快速枚舉,也是蘋果推薦的枚舉方法。它允許把集合對(duì)象的枚舉直接用作for循環(huán)的一部分,無(wú)需使用其他枚舉對(duì)象,而且比傳統(tǒng)的機(jī)遇索引的for循環(huán)效率更高?,F(xiàn)在枚舉循環(huán)使用指針運(yùn)算,讓它比使用NSEnumerator的標(biāo)準(zhǔn)方法效率更高。
要使用快速枚舉,集合類需要實(shí)現(xiàn)NSFastEnumeration協(xié)議,以向運(yùn)行庫(kù)提供關(guān)于集合的必要信息?;A(chǔ)框架中的所有集合類與NSEnumerator類都支持快速枚舉。因此不必使用while循環(huán)從NSEnumerator枚舉每個(gè)元素,直到nextObject返回nil。代碼如下:
NSArray *array = @[@"張三", @"李四", @"王五"];
for (id item in array) {
NSLog(@"item is :%@", item);
}
2015-08-28 17:28:18.619 NSEnumatroDemo[55596:3730966] item is :張三 2015-08-28 17:28:18.620 NSEnumatroDemo[55596:3730966] item is :李四 2015-08-28 17:28:18.620 NSEnumatroDemo[55596:3730966] item is :王五
4.內(nèi)部枚舉
NSArray有個(gè)實(shí)例方法叫(void)makeObjectsPerformSelector:(SEL)aSelector,它允許客戶端向數(shù)組中每個(gè)元素發(fā)送一個(gè)消息,讓每個(gè)元素執(zhí)行指定的aSelector??梢杂们懊嫣岬降娜魏我环N枚舉方法讓每個(gè)元素執(zhí)行相同的選擇器,達(dá)到相同的目的。這個(gè)方法在內(nèi)部枚舉集合并向每個(gè)元素發(fā)送performSelector:消息。這種方式的缺點(diǎn)是如果集合中任何元素不響應(yīng)選擇器,就會(huì)拋出異常。因此它主要使用于不需要太多運(yùn)行時(shí)檢查的簡(jiǎn)單操作。
- PHP設(shè)計(jì)模式之迭代器模式
- Java使用設(shè)計(jì)模式中迭代器模式構(gòu)建項(xiàng)目的代碼結(jié)構(gòu)示例
- iOS App設(shè)計(jì)模式開發(fā)中對(duì)迭代器模式的使用示例
- C++設(shè)計(jì)模式編程中的迭代器模式應(yīng)用解析
- Python使用設(shè)計(jì)模式中的責(zé)任鏈模式與迭代器模式的示例
- 使用迭代器模式來(lái)進(jìn)行Java的設(shè)計(jì)模式編程
- 學(xué)習(xí)JavaScript設(shè)計(jì)模式之迭代器模式
- 深入理解JavaScript系列(35):設(shè)計(jì)模式之迭代器模式詳解
- C++設(shè)計(jì)模式之迭代器模式
- 輕松掌握J(rèn)ava迭代器模式
相關(guān)文章
IOS開發(fā)之路--C語(yǔ)言存儲(chǔ)方式和作用域
只有你完全了解每個(gè)變量或函數(shù)存儲(chǔ)方式、作用范圍和銷毀時(shí)間才可能正確的使用這門語(yǔ)言。今天將著重介紹C語(yǔ)言中變量作用范圍、存儲(chǔ)方式、生命周期、作用域和可訪問性。2014-08-08
iOS開發(fā)Quick Actions創(chuàng)建桌面Icon快捷方式
在本文里我們給大家分享了關(guān)于iOS開發(fā)Quick Actions創(chuàng)建桌面Icon快捷方式的相關(guān)知識(shí)點(diǎn)內(nèi)容,需要的讀者們可以參考下。2019-05-05
iOS之?dāng)?shù)據(jù)解析之XML解析詳解
本篇文章主要介紹了iOS之?dāng)?shù)據(jù)解析之XML解析詳解,XML解析常見的兩種方式:DOM解析和SAX解析,有興趣的可以了解一下。2016-12-12
iOS 委托與文本輸入(內(nèi)容根據(jù)iOS編程編寫)
這篇文章主要介紹了iOS 委托與文本輸入(內(nèi)容根據(jù)iOS編程編寫) 的相關(guān)資料,需要的朋友可以參考下2016-09-09
iOS利用UITableView設(shè)置全屏分隔線的3種方法總結(jié)
這篇文章主要介紹了關(guān)于iOS利用UITableView設(shè)置全屏分隔線的幾種方法的相關(guān)對(duì)比,分析這三種的各自優(yōu)缺點(diǎn),并且分享了設(shè)置UITableView的單元格分割線離屏幕左右的距離為0的方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起看看吧。2017-11-11
iOS實(shí)現(xiàn)換膚功能的簡(jiǎn)單處理框架(附源碼)
這篇文章主要給大家介紹了關(guān)于iOS實(shí)現(xiàn)換膚功能的簡(jiǎn)單處理框架,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02

