定义
说到迭代器,我们应该是很熟悉的,不管你是写过C++代码还是写过IOS代码,你都应该有用过迭代器,比如C++的vector、list等STL对象都提供了迭代器以供程序代码可以更为方便地遍历集合元素。
迭代器为访问集合对象提供一种间接的方法,从而使得外部不需要知道集合的内部细节。集合对象的迭代器避免了集合对象本身实现的元素的遍历,使得集合的遍历更为简单、便利。迭代器一般定义了通用的访问集合元素的方法,同时提供了记录了当前元素的机制,使得可直接使用迭代器而不需要使用集合对象本身就可以访问集合。集合和迭代器的基本关系图如下图所示:
List定义了修改集合和获取集合元素的方法,而ListIterator包含了一个List对象的引用,使得迭代器可以直接地遍历和返回集合元素。在迭代器ListIterator内,定义了迭代过程访问下一元素的方法,同时也定义了一个记录当前元素的的变量_index,来看看更为详细的集合和迭代器关系图:
抽象类Aggregate定义了一个返回迭代器对象的方法createIterator,其子类重载实现了返回迭代器对象的方法。抽象类Iterator定义了迭代器应该实现的基本访问集合的方法,客户端可以使用这些抽象的接口遍历任何Aggregate类型的对象。
迭代器有两种基本的类型:内部迭代器和外部迭代器。外部迭代器供客户端使用,客户端可以通过外部迭代器访问修改集合。此外,外部迭代器也可以在Aggregate内部直接使用。提供内部迭代器的集合对象一般会为客户端定义一个接口,祸从底层每次访问一个元素,或向每个元素发送消息。
外部迭代器 | 内部迭代器 |
---|---|
客户端需要知道外部迭代器 | 客户端不需要知道外部迭代器可直接使用特俗接口访问集合 |
客户端自身创建并使用迭代器 | 集合本身创建并维护他的外部迭代器 |
客户端可以使用迭代器访问多种结合对象 | 集合可以在不修改客户端代码换个外部迭代器 |
从上述的对比中我们可以发现,迭代器的内外之分是从集合的角度来看的。
附上迭代器模式的标准定义:
适用场景
- 你希望在不知道组合对象的内部细节的情况下访问对象
- 你希望有多种方式可以遍历集合对象
- 你需要为遍历不同类型的集合对象提供统一的接口
Cocoa Touch的迭代器
示例代码
// 一般用法
NSArray *anArray = ... ;
NSEnumerator *itemEnumerator = [anArray objectEnumerator];
NSString *item;
while (item = [itemEnumerator nextObject])
{
// do something with the item
}
// Block块的迭代器
NSArray *anArray=[NSArray arrayWithObjects:@"This", @"is", @"a", @"test", nil]; NSString *string=@"test";
[anArray enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop)
{
if([obj localizedCaseInsensitiveCompare:string] == NSOrderedSame)
{
// do something else with the returned obj
*stop=YES; }
}
];
// 快速迭代器
NSArray * anArray = ... ;
for (NSString * item in anArray)
{
// do something with the item
}