《Objective-C基础教程》读书笔记5.2—数组

1集合大家族
Cocoa提供了许多集合类,如NSArray和NSDictionary,它们的实例就是为了存储其他对象而存在的。
1.1 NSArray
NSArray是一个Cocoa类,用来存储对象的有序列表。你可以在NSArray中放入任意类型的对象:NSString、Car或者其他你想要存储的对象,甚至可以是其他数组或字典对象。
NSArray类有两个限制。首先,它只能存储Objective-C的对象,而不能存储原始的C语言基础数据类型,如int、float、enum、struct和NSArray中的随机指针。同时,你也不能在NSArray中存储nil(对象的nil零值或NULL值)。有很多种方法可以避开这些限制。
1.1.1 创建数组
可以通过类方法arrayWithObjects:创建一个新的NSArray。发送一个以逗号分隔的对象列表,在列表结尾添加nil代表列表结束(这也就是不能在数组中存储nil的一个原因)。你也可以使用数组字面量格式来创建一个数组。
注意:使用字面量语法时不必在结尾处特意补上nil。
1.1.2 获取数组所包含的对象个数

  • (NSUInteger)count;
    1.1.3 也可以获取特定索引处的对象
  • (id)objectAtIndex:(NSUInteger)index;
    通过字面量访问数组的语法与C语言中访问数组项的语法类似。
    id *myObject = array[i];

    《《Objective-C基础教程》读书笔记5.2—数组》 1528645294431.jpg
    《《Objective-C基础教程》读书笔记5.2—数组》 1528645333601.jpg

    注意:在开发中,与数组常见的一个异常是NSRangeException. (uncaught exception)未捕获的异常。异常(exception)是Cocoa说明“我不知道该如何处理”的方式。你有许多方法来捕获和处理代码中的异常,比如设置全局断点。NSRangeException如果与数组相关一般指数组越界。
    NSArray也有很多特性,例如让数组给出特定对象的位置,根据当前数组中的元素创建新数组,用给定的分隔符将所有数组元素合成为一个字符串(便于创建以逗号分隔的列表),或者创建已有数组的排序版本。
    以下是NSArray数组的两个特性
    1.使用-componentsSeparatedByString:可以切分NSArray。即:将字符串切分成数组。
    2.使用 componentsJoinedByString:来合并NSArray中的元素并创建字符串。即:将数组元素合并成字符串。

    《《Objective-C基础教程》读书笔记5.2—数组》 1528646726402.jpg
    《《Objective-C基础教程》读书笔记5.2—数组》 1528646764151.jpg
    1.2 可变数组
    与NSString一样,NSArray创建的是不可变对象的数组。一旦你创建了一个包含特定数量的对象的数组,它就固定下来了: 你既不能添加任何元素也不能删除任何元素。当然数组中包含的对象是可以改变的,但数组对象本身是一直都不会改变的。
    可变数组NSMutableArray
    1.2.1 NSMutableArray通过类方法arrayWithCapacity来创建新的可变数组:

    +(id)arrayWithCapacity: (NSUInteger)numItems;
    以上的数组容量也只是数组最终大小的一个参考。容量数值之所以存在,是为了让Cocoa能够对代码进行一些优化。Cocoa既不会将对象预写入数组中,也不会用该容量值来限制数组的大小。
    1.2.2 使用addObject:在数组末尾添加对象:

    • (void)addObject:(id)anObject;
      1.2.3 删除特定索引处的对象
    • (void)removeObjectAtIndex:(NSUInteger)index;
      NSArry中的对象是从零开始编制索引的,这与C数组的规范一样。删除一个对象之后,数组中并没有留下漏洞。位于被删除对象后面的数组元素都被前移来填补空缺了。
      可变数组的其他方法也能够用来实现很多出色的操作,例如在特定索引处插入新对象、替换对象、为数组排序,还包括了从NSArray所继承的大量好用的功能。
      没有可以用来创建NSMutableArray对象的字面量语法。

      《《Objective-C基础教程》读书笔记5.2—数组》 1528726254733.jpg
      《《Objective-C基础教程》读书笔记5.2—数组》 1528726297465.jpg

      1.3 枚举
      NSArray经常要对数组中的每个元素都执行同一操作。NSEnumerator, Cocoa可以用它来表示集合中迭代出的对象。要想使用NSEnumerator, 需通过objectEnumerator向数组请求枚举器:
      -(NSEnumerator *)objectEnumerator;
      如果你想从后往前浏览某个集合,可以使用reverseObjectEnumerator这个方法。此方法主要用于数组倒序。
      在获得枚举器之后,便可以开始一个while循环,每次循环都向这个枚举器请求它的nextObject(下一个对象);
      -(id)nextObject;
      nextObject返回nil时,循环结束。这也是不能在数组中存储nil值的另一个原因: 我们没有办法判断nil是存储在数组中的数值还是代表循环结束的标志。(创建可变数组,nil代表结束,是终止符号)。
      对可变数组进行枚举操作时,有一点需要注意:你不能通过添加或删除对象这类方式来改变数组的容量。如果这么做了,枚举器会出现混乱,程序会crash。

      《《Objective-C基础教程》读书笔记5.2—数组》 1528729013596.jpg
      《《Objective-C基础教程》读书笔记5.2—数组》 1528729065990.jpg
      1.4 快速枚举
      快速枚举(fast enumerator),其实指For-In循环,这个循环体会遍历数组中的每一个元素,它比枚举器语法更加间接快速。
      与Objective-C 2.0的其他新特性一样,快速枚举不能在旧的Mac(Mac OS X 10.5之前)的系统上运行。如果你或者你的用户需要在一台不支持Objective 2.0及更新版本上的电脑运行你的程序,就不能使用快速枚举这个新语法。现在这个问题依然存在。
      最新版本的苹果编译器(基于Clang和LLVM项目)为纯C语言添加了一个代码块(block)的特性。为了支持代码块功能,苹果公司添加了一个能在NSArray中通过代码块枚举对象的方法:
      -(void)enumeratorObjectsUsingBlock: (void (^)(id obj , NSUInteger index , BOOL *stop))block;

      使用代码块代替快速枚举的原因:因为通过代码块可以让循环操作并发执行,而通过快读枚举,执行操作要一项项地线性完成。所以,如果可以使用代码块的情况下,建议使用代码块。
      现在我们有四种方法遍历数组:通过索引、使用NSEnumerator、使用快速枚举和最新的代码块方法。一般在获取数组特定下标的对象时用索引,其余大多数情况用快速枚举或者代码块。
      代码块只有在Apple LLVM编译器上才会有效。如果你还有支持Mac OS X 10.4或更早的系统,那就使用NSEnumerator。Xcode有重构功能,可以将代码转换成Objective-C 2.0, 它会自动将NSEnumerator循环转换成快速枚举。

      《《Objective-C基础教程》读书笔记5.2—数组》 1528731000547.jpg
      《《Objective-C基础教程》读书笔记5.2—数组》 1528731051126.jpg

    原文作者:天山雪莲_38324
    原文地址: https://www.jianshu.com/p/04da0fe10039
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞