【问题标题】:How to pass a block of type dispatch_block_t to a method如何将 dispatch_block_t 类型的块传递给方法
【发布时间】:2019-11-03 05:33:01
【问题描述】:

在下面的代码中,我试图将dispatch_block_t 类型的块传递给dispatch_async,如下所示。 我尝试了以下方法:

dispatch_async(defaultPriority, block1(2, 3000));
dispatch_async(defaultPriority, (^block1)(2, 3000));
dispatch_async(defaultPriority, ^(block1)(2, 3000));

但是,由于块传递给dispatch_async 方法的方式导致生成错误,因此代码无法编译。 请让我知道如何解决它。如果您能提供不同的传递方式(如果适用),那就太好了。

dispatch_block_t ^block1(int, int) = ^(int x1, int delay) {
    [NSThread sleepForTimeInterval: delay];
};
dispatch_queue_t defaultPriority = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t backgroundPriority = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);

dispatch_async(defaultPriority, block1(2, 3000));

synchName andId: (NSString *) synchId;

【问题讨论】:

    标签: objective-c grand-central-dispatch objective-c-blocks dispatch-queue


    【解决方案1】:

    dispatch_block_t 被定义为不带参数的块:

    typedef void (^dispatch_block_t)(void);
    

    因此,说“我想将具有两个参数的块定义为 dispatch_block_t”是没有意义的,因为 dispatch_block_t 不接受任何参数。

    因此,假设您要定义一个方法,该方法接受一个带有两个参数的块。你会这样做:

    - (void)foo:(void (^)(int, int))block {
        dispatch_queue_t queue = dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0);
    
        dispatch_async(queue, ^{
            block(42, 3);
        });
    }
    

    注意,我不只是将block 作为第二个参数直接传递给dispatch_async,因为dispatch_block_t 没有参数,而我的块有两个参数。因此,我将^{...} 语法用于dispatch_async 的第二个参数,并在该块内,使用提供的两个参数调用我的block。

    不管怎样,你会这样称呼它:

    void (^block1)(int, int) = ^(int value, int delay) {
        [NSThread sleepForTimeInterval:(NSTimeInterval)delay];
        NSLog(@"value = %d", value);
    };
    [self foo:block1];
    

    或者

    [self foo:^(int value, int delay) {
        [NSThread sleepForTimeInterval:(NSTimeInterval)delay];
        NSLog(@"value = %d", value);
    }];
    

    如果您还想将块的两个参数也传递给foo,那么添加这两个参数:

    - (void)fooWithValue:(int)value delay:(int)delay block:(void (^)(int, int))block {
        dispatch_queue_t queue = dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0);
    
        dispatch_async(queue, ^{
            block(value, delay);
        });
    }
    

    你会这样称呼它:

    void (^block1)(int, int) = ^(int value, int delay) {
        [NSThread sleepForTimeInterval:(NSTimeInterval)delay];
        NSLog(@"value = %d", value);
    };
    
    [self fooWithValue:2 delay:3 block:block1];
    

    dispatch_block_t 类型的优点是它让我们摆脱了上述晦涩难懂的块语法。但是我们可以为我们可能需要的任何参数组合定义自定义类型:

    typedef void (^CustomBlock)(int, int);
    

    这和dispatch_block_t 一样,除了这个有两个整数参数。

    然后您可以执行以下操作:

    - (void)fooWithValue:(int)value delay:(int)delay block:(CustomBlock)block {
        dispatch_queue_t queue = dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0);
    
        dispatch_async(queue, ^{
            block(value, delay);
        });
    }
    

    和

    CustomBlock block1 = ^(int value, int delay) {
        [NSThread sleepForTimeInterval:(NSTimeInterval)delay];
        NSLog(@"value = %d", value);
    };
    
    [self fooWithValue:2 delay:3 block:block1];
    

    这个块的语法很难记住,所以如果你忘记了语法,http://goshdarnblocksyntax.com 是一个很好的备忘单。


    顺便说一句,您的代码引用了“延迟”和sleepForTimeInterval。您通常不想使用sleepForTimeInterval。您通常会使用dispatch_after,例如要在 3 秒内完成某件事,您会:

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self doSomething];
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多