1

模式定义

迭代器: 提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部表示。

结构图

静态结构类图:

clipboard.png

  • 抽象容器(Aggregate):一般是一个接口,提供一个iterator()方法,例如java中的Collection接口,List接口,Set接口等。

  • 具体容器(ConcreteAggregate):就是抽象容器的具体实现类,比如List接口的有序列表实现ArrayList,List接口的链表实现LinkList,Set接口的哈希列表的实现HashSet等。

  • 抽象迭代器(Iterator):定义遍历元素所需要的方法,一般来说会有这么几个方法:取得第一个元素的方法first(),取得下一个元素的方法next(),判断是否遍历结束的方法isDone()(或者叫hasNext())等。

  • 迭代器实现(ConcreteIterator):实现迭代器接口中定义的方法,完成集合的迭代器。

容器类和迭代器的关系:

容器类提供一个工厂方法来创建返回相应的具体迭代器对象。
迭代器内部持有一个对容器类实例对象的引用。

CocoaTouch 框架中使用迭代器模式

迭代器类: NSEnumerator
可以使用NSEnumerator来枚举NSArray,NSDictionary和NSSet对象中的元素。
NSEnumerator本身是个抽象类,它依靠几个工厂方法,如objectEnumerator、keyEnumerator,来创建返回相应的具体迭代器对象。客户端用返回的迭代器对象遍历集合中的元素。

示例代码
- (void)iteratorMethod
{
    NSArray *array = @[@1, @2, @3, @4];
    NSEnumerator *enumerator = [array objectEnumerator];
    
    NSNumber *number;
    while (number = [enumerator nextObject]) {
        // 对number进行处理
    }
}

应用示例

先看一种数据结构--线性表: 线性表是最基本,最简单,也是最常用的一种数据结构。

clipboard.png

这里以线性表结构为例,存储结构采用链表的方式实现一个迭代器。

  • 首先创建一个结点类Node

// .h
@interface Node : NSObject

@property (nonatomic, strong, readonly) id data;
@property (nonatomic, strong, readonly) Node *nextObject;

- (void)insertItem:(id)item;
- (NodeIterator *)createNodeIterator;

@end

// .m
@interface Node()

@property (nonatomic, strong, readwrite) id data;
@property (nonatomic, strong, readwrite) Node *nextObject;

@end

@implementation Node

- (void)insertItem:(id)item
{
    Node *preNode = self;
    Node *currentNode = nil;
    
    currentNode = preNode.nextObject;
    while (currentNode) {
        preNode = currentNode;
        currentNode = currentNode.nextObject;
    }
    
    Node *newNode = [[Node alloc] init];
    newNode.data = item;
    newNode.nextObject = nil;
    
    preNode.nextObject = newNode;
}

- (NodeIterator *)createNodeIterator
{
    NodeIterator *iterator = [[NodeIterator alloc] initWithNode:self];
    return iterator;
}

@end
  • 创建一个迭代器协议类 <NodeIteratorProtocol>

@protocol NodeIteratorProtocol <NSObject>

@required
- (id)nextObject;

@end
  • 创建迭代器类 NodeIterator

// .h
@interface NodeIterator : NSObject <NodeIteratorProtocol>

- (instancetype)initWithNode:(Node *)head;

@enda

// .m
@interface NodeIterator()

@property (nonatomic, strong) Node *head;
@property (nonatomic, strong) Node *currentNode;

@end

@implementation NodeIterator

- (instancetype)initWithNode:(Node *)head
{
    self = [super init];
    if (self) {
        _head = head;
        _currentNode = head;
    }
    return self;
}

- (Node *)nextObject
{
    Node *node = nil;
    node = self.currentNode.nextObject;
    self.currentNode = node;
    return node;
}

@end
  • 客户端调用

    Node *head = [[Node alloc] init];
    [head insertItem:@"1"];
    [head insertItem:@"2"];
    [head insertItem:@"3"];
    [head insertItem:@"4"];
    
    NodeIterator *iterator = [head createNodeIterator];
    Node *item = nil;
    while (item = [iterator nextObject]) {
        NSLog(@"item = %@", item.data);
    }
  • 运行结果

clipboard.png


danielmea
28 声望8 粉丝

程序猿的逗比日常-------