设计模式中的迭代器模式在Cocoa Touch框架中的使用

 更新时间:2016年03月30日 17:20:50   作者:卡卡罗特  
这篇文章主要介绍了设计模式中的迭代器模式在Cocoa Touch框架中的使用,示例代码为传统的Objective-C,需要的朋友可以参考下

基本理解
迭代器模式(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:消息。这种方式的缺点是如果集合中任何元素不响应选择器,就会抛出异常。因此它主要使用于不需要太多运行时检查的简单操作。

相关文章

  • iOS NSNotificationCenter通知中心使用小结

    iOS NSNotificationCenter通知中心使用小结

    IOS中经常会使用到NSNotification和delegate来进行一些类之间的消息传递,这篇文章主要介绍了iOS NSNotificationCenter使用小结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11
  • iOS获取网络类型的方法汇总

    iOS获取网络类型的方法汇总

    本篇文章主要给大家汇总介绍了iOS获取网络类型的方法,主要涉及到方面的内容,对于IOS开发感兴趣的同学可以参考一下
    2015-06-06
  • IOS开发用户登录注册模块所遇到的问题

    IOS开发用户登录注册模块所遇到的问题

    最近和另外一位同事负责公司登录和用户中心模块的开发工作。通过本文给大家分享IOS开发用户登录注册模块所遇到的问题,感兴趣的朋友一起学习吧
    2016-01-01
  • 推荐一个非常棒的Titanium MVC框架

    推荐一个非常棒的Titanium MVC框架

    ChariTi是一个非常不错的Titanium MVC框架。此框架的特点是很多东西可直接通过配置文件实现,如APP的主题颜色,每个tab的内容,是否使用滑动菜单布局,是否支持tablet布局等,而且其对iOS 和 android也有很好的支持,同时也支持横屏和竖屏的转换然后使用不同的布局。
    2014-07-07
  • ios NSNotificationCenter通知的简单使用

    ios NSNotificationCenter通知的简单使用

    这篇文章主要介绍了ios NSNotificationCenter通知的简单使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • iOS利用余弦函数实现卡片浏览工具

    iOS利用余弦函数实现卡片浏览工具

    这篇文章主要为大家详细介绍了iOS利用余弦函数实现卡片浏览工具,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • IOS UITableViewCell详解及按钮点击事件处理实例

    IOS UITableViewCell详解及按钮点击事件处理实例

    这篇文章主要介绍了IOS UITableViewCell详解及按钮点击事件处理实例的相关资料,这里附有示例代码,大家可以看下如何实现按键点击事件,需要的朋友可以参考下
    2016-12-12
  • iOS开发教程之XLForm的基本使用方法

    iOS开发教程之XLForm的基本使用方法

    XLForm 是最灵活且最强大的创建动态表单的iOS库,下面这篇文章主要给大家介绍了关于iOS开发教程之XLForm的基本使用方法,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。
    2018-04-04
  • iOS开发中使用Quartz2D绘图及自定义UIImageView控件

    iOS开发中使用Quartz2D绘图及自定义UIImageView控件

    这篇文章主要介绍了iOS开发中使用Quartz2D绘图及自定义UIImageView控件的方法,代码基于传统的Objective-C,需要的朋友可以参考下
    2015-11-11
  • IOS 中UIImageView响应点击事件

    IOS 中UIImageView响应点击事件

    这篇文章主要介绍了IOS 中UIImageView响应点击事件的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下
    2017-09-09

最新评论