iOS 中的循环遍历

集合类对象

主要包括数组(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,就可以停止遍历。这对于需要在找到满足特定条件的元素后立即停止遍历的环境(如查找操作)非常有用。

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...