集合类对象
主要包括数组(NSArray 类簇)、字典(NSDictionary 类簇)、集合(NSSet 类簇),例如
NSArray *array = @[@"Apple", @"Banana", @"Cherry", @"Dates"];
NSDictionary *dictionary = @{@"One": @"Apple", @"Two": @"Banana", @"Three": @"Cherry"};
NSSet *set = [NSSet setWithObjects:@"One", @"Two", @"Three", nil];
遍历
集合类对象遍历有 enumerateObjectsXXX 和 for 两种
for 循环
for 语句
支持遍历 NSArray,不支持遍历 NSDictionay 和 NSSet
支持遍历数组对象中的每一个对象,也支持按步长进行遍历
// 遍历每一个对象
for (int i = 0; i < array.count; i++) {
NSLog("%@", array[i]);
if ([obj isEqualToString:@"Cherry"]) {
break;
}
}
// 按步长遍历
for (init i=0; i<array.count; i=i+2) {
NSLog("%@", array[i]);
}
for-in 语句
支持所有集合类对象,不支持按步长遍历
// 字典,无序遍历
for (NSString *key in dictionary) {
NSLog(@"Key: %@, Value: %@", key, [dictionary objectForKey:key]);
}
// 集合,无序遍历
for (NSString *item in set) {
NSLog(@"%@", item);
}
enumerateObjects
使用方式
// 数组
[array enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSLog(@"Item at index %lu is %@", (unsigned long)idx, obj);
// 如果遇到 "Cherry",停止遍历
if ([obj isEqualToString:@"Cherry"]) {
*stop = YES;
}
}];
// 字典
[dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSLog(@"Key: %@, Value: %@", key, obj);
}];
// 集合
[set enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
NSLog(@"Object: %@", obj);
}];
使用注意
- 如果要更改 block 外的数据,需使用 __block 修饰符
// 字典
__block int count = 0;
[dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSLog(@"Key: %@, Value: %@", key, obj);
count++;
}];
- 闭包(block) 前后无需使用 weak 和 strong 修饰
使用 NS_NOESCAPE 修饰符时,有助于编译器做优化,也用于阻止闭包捕获并保留self
,防止潜在的循环引用。
// NSDictionary.h
- (void)enumerateKeysAndObjectsUsingBlock:(void (NS_NOESCAPE ^)(KeyType key, ObjectType obj, BOOL *stop))block API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
支持并行处理元素:如果你的数据集大,并且每个元素的处理是相互独立的,那么利用 enumerateObjectsUsingBlock:
的并发功能可以提高效率。这可以通过 enumerateObjectsWithOptions:usingBlock:
方法中的 NSEnumerationConcurrent
选项来实现。
停止遍历,跳出循环:enumerateObjectsUsingBlock:
方法允许你在 block 内部提前停止遍历。只需要设置传入 block 的 stop 参数为 YES,就可以停止遍历。这对于需要在找到满足特定条件的元素后立即停止遍历的环境(如查找操作)非常有用。