Objective-C: существует ли-invoke на блоках, который принимает параметры?
Как вы, возможно, знаете, блоки принимают -invoke
:
void(^foo)() = ^{
NSLog(@"Do stuff");
};
[foo invoke]; // Logs 'Do stuff'
Я хотел бы сделать следующее:
void(^bar)(int) = ^(int k) {
NSLog(@"%d", k);
};
[bar invokeWithParameters:7]; // Want it to log '7', but no such instance method
Обычный аргумент без -invoke
работает на bar
, но он выводит бессмысленное значение.
-invoke
.
Есть ли список сообщений, принятых блоками?
(Да, я пытался использовать class_copyMethodList
для извлечения списка методов из время выполнения; кажется, его нет.)
Edit: Да, я также знаю о вызове блока обычным способом (bar(7)
;). На самом деле мне нужен селектор для метода, который я могу ввести в код библиотеки, который не принимает блоки (per-se).
2 ответа:
Само определение блока - это сумма "сообщений", которые блок может получить, в терминах вызывающих параметров / ABI.
Это происходит по нескольким причинам:
Во-первых, блок не является функцией, а указатель блока не является указателем функции. Их нельзя использовать взаимозаменяемо.Во-вторых, C ABI таков, что вы должны иметь объявление функции begin, вызываемой при компиляции сайта вызова, если параметры должны быть закодированы правильно.
Альтернативой является использование чего-то вроде NSInvocation, что позволяет кодировать аргументы индивидуально, но даже это требует полного знания C ABI для каждого отдельного аргумента. В конечном счете, если вы можете скомпилировать сайт вызова, который имеет все параметры, будь то метод Objective-C или вызов функции, с точностью, необходимой для того, чтобы сделать компилятор счастливым, вы можете преобразовать этот сайт вызова в вызов блока.То есть, если вы не проясните свой вопрос немного, то, что вы просите, либо уже поддерживается, либо почти невозможно из-за капризов C ABI.
Вы можете вызвать его как функцию:
bar(7);
Есть даже пример в документации, который использует точно такую же подпись. См. объявление и использование блок.
Лучшим справочником по поведению блоков является документBlock Language Specification (RTF). Здесь упоминаются некоторые поддерживаемые методы (копирование, сохранение и т. д.) но ничего о методе-invoke
.