1. 程式人生 > 實用技巧 >iOS 列舉器block 引數指標 BOOL *stop

iOS 列舉器block 引數指標 BOOL *stop

iOS 列舉器

列舉器是一種蘋果官方推薦的更加面向物件的一種遍歷方式,相比於for迴圈,它具有高度解耦、面向物件、使用方便等優勢。常用的有兩個 enumerateObjectsUsingBlockenumerateKeysAndObjectsUsingBlock

NSArray的列舉器方法enumerateObjectsUsingBlock用法:

- (IBAction)test3Action:(UIButton *)sender {
    
    NSArray * arr = @[@"1",@"2",@"3",@"4",@"5"];
    [arr enumerateObjectsUsingBlock:^(NSString * obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (obj.intValue ==3 ) {
            NSLog(@"stop %d",obj.intValue);
            *stop = YES;
        }
        NSLog(@"intValue %d",obj.intValue);
    }];
}

NSDictionary的列舉器方法enumerateKeysAndObjectsUsingBlock

它就一個引數就是block,這個block攜帶了三個引數,這將要把dictionary裡面的key和value每次一組傳遞到block,enumerateKeysAndObjectsUsingBlock會遍歷dictionary並把裡面所有的key和value一組一組的展示給你,每組都會執行這個block。

- (IBAction)test3Action:(UIButton *)sender {

    NSDictionary * dic = @{@"姓名":@"張三",@"年齡":@"12",@"性別":@"男"};
    [dic enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        NSLog(@"key:%@  value:%@",key,obj);
    }];

}

stop 的使用

可以通過重新賦值那個BOOL *stop來停止執行,停止遍歷同時停止呼叫block。

  • 只使用 *stop = YES; 結束列舉器,但要等到本次迴圈執行完成後才會結束列舉器。
  • 只使用 return; 結束本次迴圈,相當於for迴圈中continue的用法。
  • *stop = YES; 和 return; 同時使用,結束迴圈Block,不執行本次迴圈剩餘的程式碼,相當於for迴圈中break的用法。

1.只使用 *stop = YES; 的情況

- (IBAction)test3Action:(UIButton *)sender {
    
    NSArray * arr = @[@"1",@"2",@"3",@"4",@"5"];
    [arr enumerateObjectsUsingBlock:^(NSString * obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (obj.intValue ==3 ) {
            NSLog(@"stop %d",obj.intValue);
            *stop = YES;
        }
        NSLog(@"intValue %d",obj.intValue);
    }];
}

輸出列印內容:
ViewController.m:63 intValue 1
ViewController.m:63 intValue 2
ViewController.m:59 stop 3
ViewController.m:63 intValue 3

2.只使用 return; 的情況

- (IBAction)test3Action:(UIButton *)sender {
    
    NSArray * arr = @[@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",];
    [arr enumerateObjectsUsingBlock:^(NSString * obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (obj.intValue ==3 ) {
            NSLog(@"stop %d",obj.intValue);
            return;
        }
        NSLog(@"intValue %d",obj.intValue);
    }];
    
    NSLog(@"===========");
    for (NSString * obj in arr) {
        if (obj.intValue ==3 ) {
            NSLog(@"stop %d",obj.intValue);
            continue;
        }
        NSLog(@"intValue %d",obj.intValue);
    }
}

輸出列印內容:
ViewController.m:63 intValue 1
ViewController.m:63 intValue 2
ViewController.m:59 stop 3
ViewController.m:63 intValue 4
ViewController.m:63 intValue 5
ViewController.m:66 ===========
ViewController.m:73 intValue 1
ViewController.m:73 intValue 2
ViewController.m:69 stop 3
ViewController.m:73 intValue 4
ViewController.m:73 intValue 5

3.*stop = YES; 和 return; 同時使用

- (IBAction)test3Action:(UIButton *)sender {
    
    NSArray * arr = @[@"1",@"2",@"3",@"4",@"5"];
    [arr enumerateObjectsUsingBlock:^(NSString * obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (obj.intValue ==3 ) {
            NSLog(@"stop %d",obj.intValue);
            *stop = YES;
            return;
        }
        NSLog(@"intValue %d",obj.intValue);
    }];
    
    NSLog(@"===========");
    for (NSString * obj in arr) {
        if (obj.intValue ==3 ) {
            NSLog(@"stop %d",obj.intValue);
            break;
//            continue;
        }
        NSLog(@"intValue %d",obj.intValue);
    }

}

輸出列印內容:
ViewController.m:63 intValue 1
ViewController.m:63 intValue 2
ViewController.m:59 stop 3
ViewController.m:66 ===========
ViewController.m:73 intValue 1
ViewController.m:73 intValue 2
ViewController.m:69 stop 3

iOS 列舉器 中 stop 的實現

自己建立一個列舉器,block中宣告個帶指標的 stop,當呼叫 block的時候,獲取 stop 的地址,拿到他的值,就可以使用了

- (IBAction)test3Action:(UIButton *)sender {
    
    NSArray * arr = @[@"1",@"2",@"3",@"4",@"5"];
    [self enumerateObjects:arr UsingBlock:^(NSNumber * obj, NSUInteger idx, BOOL *stop) {
        if (obj.intValue ==3 ) {
            NSLog(@"stop %d",obj.intValue);
            *stop = YES;
        }
        NSLog(@"intValue %d",obj.intValue);
    }];
}

- (void)enumerateObjects:(NSArray *)list UsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block {
    NSUInteger idx = 0;
    for( id obj in list ){
        
        BOOL stop = NO;
        
        block(obj, idx++, &stop);
        
        if( stop ){
            break;
        }
    }
}