dispatch_block_t
определяется как замыкание, которое не принимает параметров:
typedef void (^dispatch_block_t)(void);
Поэтому нет смысла говорить «Я хочу определить замыкание с двумя параметрами и определить его какa 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];
Кстати, если вы хотите упростить этот синтаксис, вы можете определить свой собственный псевдоним типа блока:
typedef void (^CustomBlockType)(int, int);
(Обратите внимание, это похоже на определение dispatch_block_t
, за исключением того, что оно принимает два целых числа.)
Тогда вы можете делать такие вещи, как:
- (void)fooWithValue:(int)value delay:(int)delay block:(CustomBlockType)block {
dispatch_queue_t queue = dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0);
dispatch_async(queue, ^{
block(value, delay);
});
}
И
CustomBlockType 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];
});