你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> 設計模式中的迭代器模式在Cocoa Touch框架中的使用

設計模式中的迭代器模式在Cocoa Touch框架中的使用

編輯:IOS開發綜合

基本理解
迭代器模式(Iterrator):提供一個方法順序訪問一個聚合對象中的各個元素,而又不暴露該元素的內部表示。
當你訪問一個聚合對象,而且不管這些對象是什麼都需要遍歷的時候,你就應該考慮用迭代器模式。
你需要對聚集有多種方式遍歷時,可以考慮用迭代器模式。
迭代器模式就是分離了集合對象的遍歷行為,抽象出一個迭代器類來負責,這樣既可以做到不暴露集合的內部結構,又可讓外部代碼透明地訪問集合內部的數據。
迭代器定義了一個用於訪問集合元素並記錄當前元素的接口。
不同的迭代器可以執行不同的迭代策略。
外部迭代器和內部迭代器:

外部迭代器

  • 外部迭代器讓客戶端直接操作迭代過程,所以客戶端需要知道外部迭代器才能使用。但是它為客戶端提供了更多的控制
  • 客戶端創建並維護外部迭代器
  • 客戶端可以使用不同外部迭代器實現多種類型的遍歷

內部迭代器

  • 客戶端不需要知道任何外部迭代器,而是可以通過集合對象的特殊接口,或者一次訪問一個元素,或者向集合中的每個元素發送消息。
  • 集合對象本身創建並維護它的外部迭代器
  • 集合對象可以在不修改客戶端代碼的情況下,選擇不同的外部迭代器

在Cocoa Touch框架中使用迭代器模式?

    基礎框架中的NSEnumerator類實現了迭代器模式。抽象NSEnumerator類的私有具體子類返回枚舉器對象,能夠順序遍歷各種集合——數組、集合、字典,把集合中的對象返回給客戶端。

    NSDirectoryEnumerator,這個類的實例遞歸枚舉文件系統中一個目錄的內容。NSArray、NSSet、NSDictionary這樣的集合類,定義了返回與集合類型相應的NSEnumerator子類實例的方法。所有的枚舉器都以同樣的方式工作,可以在一個循環中向枚舉器發送nextObject消息,從枚舉器取得對象,直到它返回nil表示遍歷結束。
1.NSEnumerator

    我們可以使用NSEnumerator來枚舉NSArray、NSDictionary和NSSet對象中的元素。NSEnumerator本身是個抽象類,它有依靠幾個工廠方法,如objectEnumrator或keyEnumerator,來創建並返回相應的具體枚舉器對象。代碼如下:
復制代碼 代碼如下:
 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對數組進行遍歷,當消息調用[itemEnumerator nextObject]會返回nil,然後枚舉過程就結束了。

2.基於塊的枚舉

    從iOS4.0後,在NSArray、NSDictionary和NSSet對象中引入了新方法,用於基於塊的枚舉。其中一個方法叫enumerateObjectsUsingBlock:(void(^)(id obj, NSUInteger idx, BOOL *stop))block。我們可以把自己的算法定義在內嵌到消息調用之中的塊裡,或者在別的什麼地方預定義一個塊,然後作為參數傳給消息調用。如下代碼:
復制代碼 代碼如下:
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數組中有字符串"李四",那麼久把指針*stop設置為YES,以通知array對象提前停止遍歷。

    NSSet對象中基於塊的枚舉與NSArray中的非常類似,只是在塊的參數中沒有idx參數。因為集合中的元素是無序的。

    使用NSArray、NSDictionary和NSSet的內部迭代器的一個重要好處是,處理其內容的算法可以在其他地方由其他開發人員來定義。與傳統的for循環中定義的算法不同,定義清晰的塊可以被復用。當塊逐漸變大時,可把它們放到單獨的實現文件中,不跟其他代碼擠在一起。

3.快速枚舉

    從iOS2.0後提供了一種枚舉,快速枚舉,也是蘋果推薦的枚舉方法。它允許把集合對象的枚舉直接用作for循環的一部分,無需使用其他枚舉對象,而且比傳統的機遇索引的for循環效率更高。現在枚舉循環使用指針運算,讓它比使用NSEnumerator的標准方法效率更高。

    要使用快速枚舉,集合類需要實現NSFastEnumeration協議,以向運行庫提供關於集合的必要信息。基礎框架中的所有集合類與NSEnumerator類都支持快速枚舉。因此不必使用while循環從NSEnumerator枚舉每個元素,直到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.內部枚舉

    NSArray有個實例方法叫(void)makeObjectsPerformSelector:(SEL)aSelector,它允許客戶端向數組中每個元素發送一個消息,讓每個元素執行指定的aSelector。可以用前面提到的任何一種枚舉方法讓每個元素執行相同的選擇器,達到相同的目的。這個方法在內部枚舉集合並向每個元素發送performSelector:消息。這種方式的缺點是如果集合中任何元素不響應選擇器,就會拋出異常。因此它主要使用於不需要太多運行時檢查的簡單操作。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved