数组NSArray遍历
问题
你拥有对象数组,想要向数组中的每个对象发送同样的消息或是访问同样的属性。
解决方案
NSArray 对象提供了3 种内置方式来遍历对象列表。很多人都使用for-each 循环遍历数组中的每个元素。通过这种结构,可以使用相同的代码来遍历数组中的每个元素。还可以使用makeObjectsPerformSelector:withObject:方法,在这种情况下,可以传递希望每个对象都执行的方法名和一个参数。
最后,还可以通过enumerateObjectsUsingBlock:方法将代码块作为参数应用到数组中的每个对象上。该方法的作用与for-each 循环一样,但无须为循环本身编写代码,并且可以通过参数追踪当前元素的索引。
说明
由于该攻略需要一些示例,因此创建3 个NSMutableString 对象并放到新的数组中:
NSMutableString*string1 = [NSMutableString stringWithString:@"A"];
NSMutableString*string2 = [NSMutableString stringWithString:@"B"];
NSMutableString*string3 = [NSMutableString stringWithString:@"C"];
NSArray*listOfObjects = [NSArray arrayWithObjects:string1, string2,string3, nil];
要想使用for-each 循环遍历NSArray 数组,需要创建循环并提供局部变量,局部变量可以引用数组中的当前对象。你还需要添加代码供列表中的每个对象执行:
for(NSMutableString*s in listOfObjects)
{
NSLog(@"Thisstring in lowercase is %@", [s lowercaseString]);
}
for-each 循环遍历数组中的每个可变字符串并将消息写到日志中。lowercaseString 是NSString 类的成员函数,能以小写形式返回字符串。无需通过for-each 循环就可以向数组中的每个对象发送消息, 方式是发送
makeObjectsPerformSelector:withObject:消息。需要将@selector 关键字传递到方法中并将方法名放到圆括号中。在属性修饰withObject:的后面传递参数值:
[listOfObjectsmakeObjectsPerformSelector:@selector(appendString:)withObject:@"-MORE"];
这里所做的是向数组中的每个可变字符串发送appendString:消息以及字符串参数@"-MORE"。现在,每个字符串最终都会被修改,其中包含了额外的字符。
//警告:确保数组中的对象可以响应你所发出的消息。如果向数组中的对象发送它们无法响应的消息,
//那么程序就会崩溃,你会收到一条错误消息—“unrecognizedselector sent toinstance”。
可以使用块定义应用到数组中的每个对象的代码块。块是一种代码封装方式,这样一来,代码就可以被当作对象,并以参数形式传递给其他对象。借助于NSArray 方法enumerateObjectsUsingBlock:,就可以对数组中的每个元素执行代码块:
[listOfObjectsenumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
{
NSLog(@"object(%lu)'s description is%@",idx, [obj description]);
}];
这与for-each 循环的作用一样,但你只需要使用一行代码即可。此外,块还为需要引用的对象提供了内置参数和索引以帮助你追踪当前在数组中的位置。该例通过块并使用对象的description 函数与index 参数,针对列表中的每个对象向日志中写入了一条消息。参见程序清单1-1。
代码
程序清单1-1 main.m
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
@autoreleasepool {
NSMutableString *string1 = [NSMutableString stringWithString:@"A"];
NSMutableString *string2 = [NSMutableString stringWithString:@"B"];
NSMutableString *string3 = [NSMutableString stringWithString:@"C"];
NSArray *listOfObjects = [NSArray arrayWithObjects:string1, string2,
string3, nil];
for(NSMutableString *s in listOfObjects){
NSLog(@"This string in lowercase is %@", [s lowercaseString]);
}
[listOfObjects makeObjectsPerformSelector:@selector(appendString:)
withObject:@"-MORE"];
[listOfObjects enumerateObjectsUsingBlock:^(id obj, NSUInteger idx,BOOL *stop)
{
NSLog(@"object(%lu)'s description is %@",idx, [obj description]);
}];
}
return 0;
}
使用
要想使用上述代码,请从Xcode 构建并运行Mac 应用。日志消息会显示出对之前所创
建数组应用各种遍历方式后的结果:
This string inlowercase is a
This string inlowercase is b
This string inlowercase is c
object(0)'sdescription is A-MORE
object(1)'sdescription is B-MORE
object(2)'s description isC-MORE