2015-12-24 4 views
1

Немного смутитесь вопросом о том, как передать блок методу, но без определенных (конкретных) параметров.Как определить блок с универсальной сигнатурой

так:

- (void)someMethodWithBlockAsParam:(generic block)block 

это вообще возможно в отношении к Obj-C

Кажется, я видел этот трюк где-то, но не могу вспомнить, где.

Благодарим заранее.

+1

Не могли бы вы передать указатель-на-пустоту и литые? Видеть. например http://stackoverflow.com/questions/11106224/how-to-cast-blocks-to-and-from-void – matt

+0

@matt - безусловно, бросая указатель на объект, блок, на указатель пустоты не самый лучший выбор в мире ARC ... – CRD

+0

@CRD Я не вижу, что он имеет отношение к ARC. Ответ на вопрос, который я связал, показывает вам, как обращаться с управлением памятью.Pointer-to-void _is_ общий тип в C/Objective-C; существует множество ситуаций, когда мы передаем указатель объекта в виде указателя на пустоту. – matt

ответ

4

Вам необходимо объявить что-то, иначе колл-сайт для этого блока не будет знать, что передать или что ожидать взамен. В частности, ему нужно знать, будут ли они объективными объектами C или нет, потому что в противном случае они не могут правильно их пересчитать.

Если вы просто хотите блок, который не имеет аргументов и ничего не возвращает (обратный вызов, в основном), то вы можете использовать dispatch_block_t:

- (void)someMethodWithBlockAsParam:(dispatch_block_t)block 
+0

Возможно, он хочет иметь возможность передать общий блок, а на принимающей стороне - передать конкретную подпись перед тем, как на самом деле называть ее (например, вы будете делать с переменными и 'void *'). Не уверен, что это возможно. –

+1

Умм, если вы хотите такой блок, вы используете 'dispatch_block_t'. Вот для чего это. – Avi

0

Как насчет определить блок с одним NSDictionary параметром, где вы можете разместить любое число и любые типы объектов в качестве параметров?

typedef void (^aBlock)(NSDictionary* parameters); 
2

запутаться немного с вопросом о том, как передать блок методу, но без определенных (конкретных) Params.

Это не для меня ясно, что именно вы просите здесь, но это звучит, как вы хотите, чтобы иметь возможность пройти любой блок к способу, который предположительно на более позднем этапе вы отбрасываемой к определенному типу блока так вы можете это назвать. Если это так:

Блок в современных (после конца 2014 года - см. this question and answer для почему эта дата) Объект ARC Objective-C - полностью автоматически управляемый объект. Поэтому для передачи любого блока может использоваться стандартный тип «любой объект» id.

Например дано:

// a specific block type 
typedef id (^SelectBlock)(NSArray *, NSUInteger); 

// method which takes a general object and casts to a specific block type 
- (void) useBlock:(id)blockObj 
{ 
    SelectBlock sb = (SelectBlock)blockObj; 
    id item = sb(@[@"apple", @"pear", @"plum"], 2); 
    NSLog(@"Result: %@", item); 

}

// method which pass a block as "any object" 
- (void) test:(NSUInteger)offset 
{ 
    SelectBlock mySelect = ^(NSArray *collection, NSUInteger index) 
          { 
          return collection[index-offset]; 
          }; 
    [self useBlock:(id)mySelect]; 
} 

тогда вызов:

[self test:1]; 

приведет к pear выводимого.

Передача блока «в общем» таким образом полезна только в том случае, если исходный тип каким-то образом известен, так что id напечатанное значение может быть возвращено к правильному типу блока для вызова блока.

+0

Хороший ответ. Конечно, если переданный блок не соответствует сигнатуре, на которую он выполняется, вызов вызывает запуск ошибки во время выполнения, правильно? –

+0

@NicolasMiari - абсолютно! Это стандартная проблема, когда вы отбрасываете информацию о типе и не привязаны к блокам, если вы возвращаетесь к неправильному типу, могут случиться плохие вещи. Отсюда комментарий в последнем абзаце. – CRD

Смежные вопросы