【问题标题】:How to use a stop condition on a block like the enumerateObjectsUsingBlock from the NSDictionary class?如何在 NSDictionary 类中的 enumerateObjectsUsingBlock 等块上使用停止条件?
【发布时间】:2013-04-07 22:28:34
【问题描述】:

我想在我的类上创建一个方法,例如 enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) 来自 NSDictionary 类。

我对块的使用有一点了解,但我无法弄清楚如何使enumerateObjectsUsingBlock 函数使用的停止条件。有什么建议吗?

【问题讨论】:

    标签: objective-c pass-by-reference objective-c-blocks


    【解决方案1】:

    stop 标志是这样使用的:

    [coll enumerateUsingBlock:^(id o, NSUInteger i, BOOL *stop) {
          if (... check for stop ... ) {
               *stop = YES;
               return;
          }
     }];
    

    当枚举块返回时,集合检查*stop。如果是YES,则停止枚举。

    它以这种方式实现,而不是返回值,因为这允许并发枚举而不检查块的返回值(这会产生开销)。 IE。在并发枚举中,集合可以dispatch_async() 任意数量的同时迭代并定期检查*stop。每当*stop 转换为YES 时,它就会停止调度更多块(这也是stop 标志不是硬停止的原因;一些未指定数量的迭代可能仍在进行中)。

    在您的迭代器中,您可以这样做:

     BOOL stop = NO;
     for(...) {
         enumerationBlock(someObj, someIndex, &stop);
         if (stop) break;
     }
    

    【讨论】:

    【解决方案2】:

    以下代码定义了一个方法,该方法将块作为参数并一直执行,直到块将shouldStop 设置为NO

    - (void)myMethod:(void(^)(BOOL *stop))aBlock {
        BOOL shouldStop = NO;
        while (!shouldStop) {
            aBlock(&shouldStop);
        }
    }
    

    解释很简单。块是一个接受一些参数的函数。在这种情况下,我们将一个指向我们拥有的BOOL 变量的指针作为参数传递。通过这样做,我们允许块设置该变量并 - 在这种情况下 - 指示循环应该停止。

    此时,传递的块可以做类似的事情

    [self myMethod:^(BOOL *stop) {
          if (arc4random_uniform(1)) {
              *stop = YES;
          }
    }];
    

    【讨论】:

      猜你喜欢
      • 2014-08-04
      • 1970-01-01
      • 1970-01-01
      • 2013-05-06
      • 2018-03-20
      • 1970-01-01
      • 1970-01-01
      • 2022-01-12
      • 1970-01-01
      相关资源
      最近更新 更多