OC中的Values——and——Collections

值和集合

  • 在OC中可以使用C中的基本数据类型。
  • 可以在类的实现里面对这些基本数据类型的属性进行C中的:++ – += -= *=等操作。
  • 如下所示:
//---------接口声明-----------
@interface XYZPerson : NSObject
@property int age;
-(void)gettingOlder;
@end
//----------接口实现-----------
@implementation XYZPerson

-(void)gettingOlder{
    _age +=1;
    //same as
    ++_age;
    //还可以像下面这样
    self.age = self.age + 1;
    self.age++;
}

@end

OC中的额外类型

  • 比如BOOL型,有YES,NO两个值,分别对应0和1。
  • 某些框架类中的方法使用到了OC中的special scalar numeric types,比如说NSInteger、CGFloat。
  • NSInteger和NSUInteger在不同的目标平台上面的位宽不一样。32位平台上它们分别对应32位有符号和无符号整形,在64位平台上它们都是64位的。

It’s best practice to use these platform-specific types if you might be passing values across API boundaries (both internal and exported APIs), such as arguments or return values in method or function calls between your application code and a framework.

若需要向某个框架外的API传递参数,比如你的应用代码和框架之间的参数传递,最好使用这些与平台相关的数据类型。
- 在64位的OSX系统内,int在OC中是32位的。而long int是64位的。
- float和double分别是32位和64位的。

Some Cocoa and Cocoa Touch API use C structures to hold their values.
- 有些框架内的API使用C的struct来保存值。

NSString *mainString = @"This is a long string";
NSRange substringRange = [mainString rangeOfString:@"long"];
  • substringRange的值为{10,4},表示long是从第十个字符开始,长度为4。
//Strings Are Represented by Instances of the NSString Class

NSString *firstString = [[NSString alloc] initWithCString:"Hello World!"
                                                     encoding:NSUTF8StringEncoding];
    NSString *secondString = [NSString stringWithCString:"Hello World!"
                                                encoding:NSUTF8StringEncoding];
    NSString *thirdString = @"Hello World!";
  • OC内使用NSString实例来保存字符串。
  • 基本的NSString类对象是immutable的。

If you need to represent a different string, you must create a new string object
- 在使用NSString类的时候,如果需要表示另外一个字符串,就必须建立一个新的对象。

NSString *name = @"John";
name = [name stringByAppendingString:@"ny"];    // returns a new string object

The NSMutableString class is the mutable subclass of NSString

  • NSMutableString类是NString的子类,允许用户使用时修改其中存放的字符串。
  • 这个类的使用例子:
NSMutableString *name = [NSMutableString stringWithString:@"John"];
[name appendString:@"ny"];   // same object, but now represents "Johnny"

Format Strings Are Used to Build Strings from Other Objects or Values

  • 格式化字符串用作使用其他对象或值建立新对象
  • 如下所示:
int magicNumber = ...
NSString *magicString = [NSString stringWithFormat:@"The magic number is %i", magicNumber];
  • 详见 String Format Specifiers和String Programming Guide。

NSNumber类

The NSNumber class is used to represent any of the basic C scalar types, including char, double, float, int, long, short, and the unsigned variants of each, as well as the Objective-C Boolean type, BOOL.
- NSNumber可以用来表示任何的C数值类型,int、long、short、double、float、char,,以及它们的无符号形式。另外还有OC种的布尔类型BOOL。
you have a variety of options to create NSNumber instances, including allocation and initialization or the class factory methods:
- 有多种建立NSNumber的方法,比如使用alloc和init,以及类的构造方法:

//使用alloc分配内存和init初始化方法
NSNumber *magicNumber = [[NSNumber alloc] initWithInt:42];
NSNumber *unsignedNumber = [[NSNumber alloc] initWithUnsignedInt:42u];
NSNumber *longNumber = [[NSNumber alloc] initWithLong:42l];
NSNumber *boolNumber = [[NSNumber alloc] initWithBOOL:YES];

//直接使用构造方法
NSNumber *simpleFloat = [NSNumber numberWithFloat:3.14f];
NSNumber *betterDouble = [NSNumber numberWithDouble:3.1415926535];
NSNumber *someChar = [NSNumber numberWithChar:'T'];
  • 还可以使用OC的字面量来建立NSNumber的实例:
  • 前面都带@符号
NSNumber *magicNumber = @42;
NSNumber *unsignedNumber = @42u;
NSNumber *longNumber = @42l;
NSNumber *boolNumber = @YES;
NSNumber *simpleFloat = @3.14f;
NSNumber *betterDouble = @3.1415926535;
NSNumber *someChar = @'T';
  • 上面这些代码和使用NSNumber的构造方法是一个效果。
  • 获得这些数值的accessor如下:
int scalarMagic = [magicNumber intValue];
unsigned int scalarUnsigned = [unsignedNumber unsignedIntValue];
long scalarLong = [longNumber longValue];

BOOL scalarBool = [boolNumber boolValue];

float scalarSimpleFloat = [simpleFloat floatValue];
double scalarBetterDouble = [betterDouble doubleValue];

char scalarChar = [someChar charValue];

The NSNumber class also offers methods to work with the additional Objective-C primitive types.

  • NSNumber类提供了和其他OC原子类型协作的一些对象方法。
    NSInteger anInteger = 64;
    NSUInteger anUnsignedInteger = 100;

    NSNumber *firstInteger = [[NSNumber alloc] initWithInteger:anInteger];
    NSNumber *secondInteger = [NSNumber numberWithUnsignedInteger:anUnsignedInteger];

    NSInteger integerCheck = [firstInteger integerValue];
    NSUInteger unsignedCheck = [secondInteger unsignedIntegerValue];

All NSNumber instances are immutable, and there is no mutable subclass; if you need a different number, simply use another NSNumber instance.

  • 所有的NSNumber类对象都是不可修改的,也没有可修改子类。如果要表示一个不同的值,只有重新建立一个NSNumber对象。

**Note: **NSNumber is actually a class cluster. This means that when you create an instance at runtime, you’ll get a suitable concrete subclass to hold the provided value. Just treat the created object as an instance of NSNumber.

  • 注意:实际上NSNumber是一个类集合。也就是说假如你需要建立一个特定数值类型的对象,这个类集中合适的子类就会被提供给你。只是将这个建立起来的对象当做NSNumber类对象来对待。

Represent Other Values Using Instances of the NSValue Class——使用NSValue类表示其它数值类型

NSNumber class is itself a subclass of the basic NSValue class.which provides an object wrapper around a single value or data item

  • NSNumber类是NSValue类的子类,提供的是对数值或数据元素的封装器功能。

NSValue can also be used to represent pointers and structures.

  • NSValue可以支持C中的基本数值类型,还支持表示指针和结构体。

The NSValue class offers various factory methods to create a value with a given standard structure, which makes it easy to create an instance to represent.

-在NSValue类里面提供了许多的构造方法表示一个给定的结构,以便于建立对象。代码如下所示:(这样有毛用?)

NSString *mainString = @"This is a long string";
NSRange substringRange = [mainString rangeOfString:@"long"];
NSValue *rangeValue = [NSValue valueWithRange:substringRange];

It’s also possible to create NSValue objects to represent custom structures. If you have a particular need to use a C structure (rather than an Objective-C object) to store information

  • NSValue对象可以表示自定义结构,如果你在工作中需要使用C中的结构体(而不是OC中的对象)存储信息
typedef struct {
    int i;
    float f;
} MyIntegerFloatStruct;

you can create an NSValue instance by providing a pointer to the structure as well as an encoded Objective-C type. The @encode() compiler directive is used to create the correct Objective-C type
- 上面的结构可以存储在NSValue类对象里,只需要提供一个该结构的指针即可,它就相当于一个OC类型。使用@encode()编译指令来建立一个合适的OC类型。

//定义一个MyIntegerFloatStruct类变量aStruct
struct MyIntegerFloatStruct aStruct;
//对结构内的变量赋值
    aStruct.i = 42;
    aStruct.f = 3.14;
//两个参数,第一个是aStruct变量的地址,第二个是使用@encode编译器指令建立的ObjType
NSValue *structValue = [NSValue value:&aStruct
                             withObjCType:@encode(MyIntegerFloatStruct)];

Most Collections Are Objects

Although it’s possible to use a C array to hold a collection of scalar values, or even object pointers, most collections in Objective-C code are instances of one of the Cocoa and Cocoa Touch collection classes, like NSArray, NSSet and NSDictionary.

  • 虽然可以使用C数组来存储数值集合、对象指针集合,但OC中的绝大多数集合都是框架类NSArray、NSSet、NSDictionary的实例。它们里存放的必须是OC类的对象。

    If you need to add a scalar value, you must first create a suitable NSNumber or NSValue instance to represent it.

  • 如果需要向它们里添加一个数值,必须首先建立一个合适的NSNumber或NSValue对象来表示这个数值。

    collection classes use strong references to keep track of their contents

  • 集合类使用强引用来追踪它里面的对象。

  • 就是说集合里面的对象生命期至少是和这个集合的生命期相同。详见Manage the Object Graph through Ownership and Responsibility.
  • OC集合类型中提供了许多的特殊方法可以对其中对象进行操作。

The basic NSArray, NSSet and NSDictionary classes are immutable, which means their contents are set at creation. Each also has a mutable subclass to allow you to add or remove objects at will.

  • 基本的NSArray、NSSet、NSDictionary都是immutable的,即它们里面存放的对象在定义后无法再次加入,但是它们都有mutable子类可供使用。
  • 更多可用的集合类详见 Collections Programming Topics.

Arrays Are Ordered Collections——数组是一种顺序集合

The only requirement is that each item is an Objective-C object— there’s no requirement for each object to be an instance of the same class.
- 唯一的条件就是待存放的元素都是OC中的对象,但是不需要让每一个对象都是相同类型的。

Creating Arrays建立数组

you can create an array through allocation and initialization, class factory methods, or literal syntax.
- 可用使用alloc和init、类构造方法、字面量来建立数组。

There are a variety of different initialization and factory methods available, depending on the number of objects.

  • OC数组内有许多不同init和构造方法可用,这和对象的数目相关:
+ (id)arrayWithObject:(id)anObject;
+ (id)arrayWithObjects:(id)firstObject, ...;
- (id)initWithObjects:(id)firstObject, ...;

The arrayWithObjects: and initWithObjects: methods both take a nil-terminated, variable number of arguments, which means that you must include nil as the last value

arrayWithObjects和initWithObjects构造方法都是以nil参数结尾,并且未限制参数的数量。

NSArray *someArray =
  [NSArray arrayWithObjects:someObject, someString, someNumber, someValue, nil];
  • 数组下标从零开始。
  • 但是下面的例子中,列出了一个需要注意的事项:假如中间的某个对象是nil,那么这个数组会被非人为地截短。
id firstObject = @"someString";
id secondObject = nil;
id thirdObject = @"anotherString";
NSArray *someArray =
  [NSArray arrayWithObjects:firstObject, secondObject, thirdObject, nil];
  • 以上面的方法建立的数组,secondObject的值是nil,那建立起来的数组就只包含一个firstObject。

    nil would be interpreted as the end of the list of items.

  • 记住nil是作为对象列表的结束标志来使用的。

Literal Syntax

  • 使用字面量建立数组的方法:
NSArray *someArray = @[firstObject, secondObject, thirdObject];

You should not terminate the list of objects with nil when using this literal syntax, and in fact nil is an invalid value. You’ll get an exception at runtime if you try to execute the following code.

  • 这种方法中,记住不能使用nil作为结束标志。因为这种方式对数组赋值时,nil是不合法的输入,如下所示:
id firstObject = @"someString";
id secondObject = nil;
NSArray *someArray = @[firstObject, secondObject];
// exception: "attempt to insert nil object"
  • 但是如果想在里面表示nil的话,必须使用单独的类:NSNull。详见Represent nil with NSNull.

Querying Array Objects

Once you’ve created an array, you can query it for information like the number of objects, or whether it contains a given item:
- 建立数组之后,就可以查询它里面的信息了。比如对象数目,或者是里面是否包含特定对象:

    //对象方法count用于获得对象数目
    NSUInteger numberOfItems = [someArray count];
    //containsObject方法用于查询特定对象
    if ([someArray containsObject:someString]) {
        ...
    }

You can also query the array for an item at a given index. You’ll get an out-of-bounds exception at runtime if you attempt to request an invalid index.

也可以通过下标查询。如果尝试越界的下标查询,则会出现运行时错误。可以像下面这样保证数组中有对象才进行查询:

//数组内存放对象数目大于0才进行查询
if ([someArray count] > 0) {
        //使用objectAtIndex方法获得指定下标对象:
        NSLog(@"First item is: %@", [someArray objectAtIndex:0]);
    }
  • 和C中一样,也可以使用[]来指定访问下标。

Sorting Array Objects

使用下面的方式可以对原数组排序并生产新数组:

//原unsortedStrings里面的对象未排序
NSArray *unsortedStrings = @[@"gammaString", @"alphaString", @"betaString"];
//使用sortedArrayUsingSelector方法来获得一个排序后的新对象,并赋值给sortedStrings,“选择器selector使用compare方法”
    NSArray *sortedStrings =
                 [unsortedStrings sortedArrayUsingSelector:@selector(compare:)];

虽然NSArray是不可变的,但不会影响到它里面存放的对象,看如下代码:

NSMutableString *mutableString = [NSMutableString stringWithString:@"Hello"];
NSArray *immutableArray = @[mutableString];
//元素数目>0
 if ([immutableArray count] > 0) {
        //将下标0的元素赋值给string
        id string = immutableArray[0];
        //当string是可变字符串类的话
        if ([string isKindOfClass:[NSMutableString class]]) {
            //修改里面的值为World!
            [string appendString:@" World!"];
        }
    }
  • 没有改变immutableArray数组,但可以改变其中的mutable的string。

If you need to be able to add or remove objects from an array after initial creation, you’ll need to use NSMutableArray.

  • 假如要修改array本身存放的对象,则使用NSMutableArray.
    NSMutableArray *mutableArray = [NSMutableArray array];
    [mutableArray addObject:@"gamma"];
    [mutableArray addObject:@"alpha"];
    [mutableArray addObject:@"beta"];

    [mutableArray replaceObjectAtIndex:0 withObject:@"epsilon"];

It’s also possible to sort a mutable array in place, without creating a secondary array.

  • 可以直接对mutable的数组进行排序,而不用重复创建对象:
[mutableArray sortUsingSelector:@selector(caseInsensitiveCompare:)];

Sets Are Unordered Collections

  • 集合是无序对象集

An NSSet is similar to an array, but maintains an unordered group of distinct objects.

NSSet和NSArray类似,只是里面的对象彼此之间不存在顺序关系。

Because sets don’t maintain order, they offer a performance improvement over arrays when it comes to testing for membership.

sets并没有在内部维护对象间顺序,在归属测试的时候可以比数组有更好的性能。

The basic NSSet class is again immutable, so its contents must be specified at creation, using either allocation and initialization or a class factory method.

  • 基本的NSSet类是immutable的,所以它存放的对象必须在建立set的时候就指定。可以使用alloc和init或类构造方法来建立set:
NSSet *simpleSet =
      [NSSet setWithObjects:@"Hello, World!", @42, aValue, anObject, nil];

As with NSArray, the initWithObjects: and setWithObjects: methods both take a nil-terminated.

  • 和NSArray类似,NSSet中的initWithObjects和setWithObjects方法都需要以nil作为结束标志。以及可变数量的参数。
  • set只会存放某对象的一次引用,即使是你多次加入某个对象。即它里面的对象都是唯一的。详见Sets: Unordered Collections of Objects.

Dictionaries Collect Key-Value Pairs——字典用于存放关键字值配对

Rather than simply maintaining an ordered or unordered collection of objects, an NSDictionary stores objects against given keys, which can then be used for retrieval.

  • 比起仅仅维护一个有序或无序集,使用NSDictionary可以存放对象和关键字的对应关系,这样就可以用于检索对象。

It’s best practice to use string objects as dictionary keys.

  • 使用字符串字面值作为字典的关键字:@“hello”…

Note: It’s possible to use other objects as keys, but it’s important to note that each key is copied for use by a dictionary and so must support NSCopying.
If you wish to be able to use Key-Value Coding, however, as described in Key-Value Coding Programming Guide, you must use string keys for dictionary objects.
- 可以用其他类型对象作为关键字,但需要注意的是,字典中用作关键字都是对象的拷贝,所以用作关键字的对象必须支持NSCopying。如果你需要使用Key-Value Coding,你就必须使用string类的对象作为关键字。(Key-Value Coding详见Key-Value Coding Programming Guide。)

Creating Dictionaries——建立字典

  • 可以使用alloc加init或者是构造方法建立字典:
//同样以nil结尾,是按 对象,关键字 的顺序进行建立的
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                   someObject, @"anObject",
             @"Hello, World!", @"helloString",
                          @42, @"magicNumber",
                    someValue, @"aValue",
                             nil];

Objective-C also offers a literal syntax for dictionary creation

  • 也可以使用字面量创建:
NSDictionary *dictionary = @{
                  @"anObject" : someObject,
               @"helloString" : @"Hello, World!",
               @"magicNumber" : @42,
                    @"aValue" : someValue
    };

Note that for dictionary literals, the key is specified before its object and is not nil-terminated.

  • 注意当在字典里面使用字面量的时候,关键字是在它索引的对象之前指定的,而且没有nil结束标志。
  • 建立字典后,就可以通过关键字来索引对象了:
//字典对象的objectForKey方法,使用关键字作为参数,返回一个对象,如果没有找到则返回nil。
NSNumber *storedNumber = [dictionary objectForKey:@"magicNumber"];
  • 也可以使用如下语法,和上面的同样效果:
//字典对象用关键字作为下标来进行索引,和数组[]类似。
NSNumber *storedNumber = dictionary[@"magicNumber"];

Mutability——可变性

If you need to add or remove objects from a dictionary after creation, you need to use the NSMutableDictionary subclass.

  • 如果想在字典创建后动态地添加或移除对象,则需要使用NSMutableDictionary.
  • 修改方法如下所示:
//dictionary的setObject方法,第一个参数是对象,第二个参数是关键字
[dictionary setObject:@"another string" forKey:@"secondString"];
//remove方法,只需要指定关键字
[dictionary removeObjectForKey:@"anObject"];

Represent nil with NSNull——使用NSNull代表nil

It’s not possible to add nil to the collection classes described in this section because nil in Objective-C means “no object.” If you need to represent “no object” in a collection, you can use the NSNull class.

  • 在Collection中需要用到nil,但nil表示是没有对象,当一个集中存放对象时,需要放入一个代表no object的对象,则使用NSNull类,如下所示:
//定义了一个末尾元素是null值对象的数组
NSArray *array = @[ @"string", @42, [NSNull null] ];

NSNull is a singleton class, which means that the null method will always return the same instance. This means that you can check whether an object in an array is equal to the shared NSNull instance.

  • NSNull是一个独立的类,即null方法总是会返回同一个对象null,可以使用这个特性来检查数组中是否有对象和共享的NSNull对象相同。如下所示:
//若数组中有和NSNull的null方法返回的对象相同类型的对象,则输出:发现一个null对象。
for (id object in array) {
        if (object == [NSNull null]) {
            NSLog(@"Found a null object");
        }
    }

Use Collections to Persist Your Object Graph——使用Collections来保存对象关系

The NSArray and NSDictionary classes make it easy to write their contents directly to disk.

  • 使用NSArray和NSDictionary类可以方便地将它们中的内容直接保存到磁盘上面,如下所示:
//指定文件fileURL
NSURL *fileURL = ...
//数组array
    NSArray *array = @[@"first", @"second", @"third"];
//输出成功标志success为YES,表示array的writeToURL方法成功
    BOOL success = [array writeToURL:fileURL atomically:YES];
    //若不成的功,则。。。
    if (!success) {
        // an error occured...
    }

If every contained object is one of the property list types (NSArray, NSDictionary, NSString, NSData, NSDate and NSNumber), it’s possible to recreate the entire hierarchy from disk.

  • 再假如集包含的对象也是Property list types (NSArray, NSDictionary, NSString, NSData, NSDate and NSNumber),则可以将这种层次关系写入到磁盘,便于之后重现,代码如下所示:
//指定文件
 NSURL *fileURL = ...
 //NSArray类方法arrayWithContentOfURL
    NSArray *array = [NSArray arrayWithContentsOfURL:fileURL];
    if (!array) {
        // an error occurred...
    }
  • 关于属性列表的更多内容请见: Property List Programming Guide.

If you need to persist other types of objects than just the standard property list classes shown above, you can use an archiver object, such as NSKeyedArchiver, to create an archive of the collected objects.

  • 如果你想保存除了标准的属性列表类意外的其他类型对象集,你可以使用归档对象,例如NSKeyArchiver,来建立一个对象集的归档。

The only requirement to create an archive is that each object must support the NSCoding protocol.This means that each object must know how to encode itself to an archive (by implementing the encodeWithCoder: method) and decode itself when read from an existing archive (the initWithCoder: method).

  • 集中的对象唯一要求是:每个对象都必须支持NSCoding协议,即里面的每个对象都必须知道如何编码它自身到一个归档(实现了encodeWithCoder:方法),以及将它自身从一个归档解码(实现了initWithCode:方法)。

The NSArray, NSSet and NSDictionary classes, and their mutable subclasses, all support NSCoding, which means you can persist complex hierarchies of objects using an archiver. If you use Interface Builder to lay out windows and views, for example, the resulting nib file is just an archive of the object hierarchy that you’ve created visually. At runtime, the nib file is unarchived to a hierarchy of objects using the relevant classes.

  • NSArray、NSSet、NSDictionary类以及它们的可变子类都支持NSCoding协议,所有可以使用归档存放这些对象内的层次关系。例如你使用Interface Builder来创建窗口或视图,那么生成的nib文件就是一个你可视化创建的对象之间层次关系通过encode保存到磁盘上,而在运行时,使用nib文件decode后,就会生成与你创建时相同的对象层次关系。
  • 更多内容详见For more information on Archives, see Archives and Serializations Programming Guide.

Use the Most Efficient Collection Enumeration Techniques使用集的高性能枚举技术

Objective-C and Cocoa or Cocoa Touch offer a variety of ways to enumerate the contents of a collection. Although it’s possible to use a traditional C for loop to iterate over the contents.

虽然可以使用C中的循环来遍历一个集,但OC和框架类中提供了大量的途径去枚举集中的内容。使用C风格枚举如下所示:

//定义一个count作为iteration。
int count = [array count];
    for (int index = 0; index < count; index++) {
        id eachObject = [array objectAtIndex:index];
        ...
    }
  • 最好的方法还是使用下列技术进行枚举。

Fast Enumeration Makes It Easy to Enumerate a Collection——Fast Enumeration技术(快速枚举)

Many collection classes conform to the NSFastEnumeration protocol, including NSArray, NSSet and NSDictionary. This means that you can use fast enumeration, an Objective-C language-level feature.

  • 许多集类型都遵循NSFastEnumeration协议,包括NSArray、NSSet和NSDictionary,即你可以在其上用OC语言层级功能——快速枚举。
  • 数组或集合中快速枚举的语法如下:
//对collection中每一个Type类型的变量
for (<Type> <variable> in <collection>) {
        ...
    }
  • 比如在一个数组中:
//对数组中每一个对象进行输出(log)
for (id eachObject in array) {
        NSLog(@"Object: %@", eachObject);
    }
  • 对于字典,则是使用关键字作为iteration:
//字典中每一个NSString类的关键字
for (NSString *eachKey in dictionary) {
        //因为还不知道每个关键字对于对象的类型,故用id
        id object = dictionary[eachKey];
        //输出格式为:“对象:关键字”
        NSLog(@"Object: %@ for key: %@", object, eachKey);
    }
  • 快速枚举类似于C中的for循环,可以在里面使用break终止循环,也可以使用continue来进入下一次循环。

If you are enumerating an ordered collection, the enumeration proceeds in that order. For an NSArray, this means the first pass will be for the object at index 0, the second for object at index 1, etc. If you need to keep track of the current index, simply count the iterations as they occur:

  • 如果枚举一个顺序集,那枚举过程也是按顺序的。比如NSArray,枚举过程是从下标0开始,然后到1,以此类推。如果你要追踪当前下标,则直接使用该下标即可。
int index = 0;
    for (id eachObject in array) {
        NSLog(@"Object at index %i is: %@", index, eachObject);
        index++;
    }

You cannot mutate a collection during fast enumeration, even if the collection is mutable. If you attempt to add or remove a collected object from within the loop, you’ll generate a runtime exception.

  • 不能在快速枚举的过程中修改一个集,就算集本身是mutable的也一样。如果你尝试在枚举的过程中添加或删除一个对象,则会出现运行时异常。

Most Collections Also Support Enumerator Objects——大部分集都支持枚举对象

It’s also possible to enumerate many Cocoa and Cocoa Touch collections by using an NSEnumerator object.

  • Cocoa框架中的许多集都可以使用NSEnumerator对象来进行枚举。

You can ask an NSArray, for example, for an objectEnumerator or a reverseObjectEnumerator. It’s possible to use these objects with fast enumeration.

  • 可以让一个NSArray类对象来使用objectEnumerator或reverseObjectEnumerator枚举器。这两个枚举器都可以用作快速枚举。
//对array使用枚举器reverseObjectEnumerator,再进行快速枚举(按与array正向相反顺序)
for (id eachObject in [array reverseObjectEnumerator]) {
        ...
    }

It’s also possible to iterate through the contents by calling the enumerator’s nextObject method repeatedly.

  • 也可以用Enumerator的nextObject方法来作循环,遍历集,如下所示:
 id eachObject;
    while ( (eachObject = [enumerator nextObject]) ) {
        NSLog(@"Current object is: %@", eachObject);
    }

a while loop is used to set the eachObject variable to the next object for each pass through the loop. When there are no more objects left, the nextObject method will return nil, which evaluates as a logical value of false so the loop stops.

  • 上面代码中使用while循环来设置eachObject变量每次都指向下一个对象。当集中没有对象的时候,即nextObject会返回一个nil,则循环条件假,则会退出循环。

Note: Because it’s a common programmer error to use the C assignment operator (=) when you mean the equality operator (==), the compiler will warn you if you set a variable in a conditional branch or loop, like this:

if (someVariable = YES) {
    ...
}

If you really do mean to reassign a variable (the logical value of the overall assignment is the final value of the left hand side), you can indicate this by placing the assignment in parentheses, like this:

if ( (someVariable = YES) ) {
    ...
}
  • 注意:如果想在逻辑条件中使用赋值(=)而不是判等(==),则需要将赋值语句放置在括号内,这样才能避免编译警告。

As with fast enumeration, you cannot mutate a collection while enumderating. And, as you might gather from the name, it’s faster to use fast enumeration than to use an enumerator object manually.

  • 和快速枚举类似,你在使用枚举对象的时候也不能修改集。也许从名字就可以发现,比起手动使用枚举对象,快速枚举性能会更好。

Many Collections Support Block-Based Enumeration

It’s also possible to enumerate NSArray, NSSet and NSDictionary using blocks. Blocks are covered in detail in the next chapter.

  • 也可以使用blocks来对NSArray、NSSet、NSDictionary进行枚举,下一章将讲述这些内容。

你可能感兴趣的:(oc,界面)