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
работает <<24 > , но он печатает бессмысленное значение.
Я не могу найти такое прямое сообщение, которое могу отправить в блок, а также не могу найти исходную документацию, описывающую, как блоки принимают -invoke
.
Есть ли список сообщений, принятых блоками?
(Да, я попытался использовать class_copyMethodList
для извлечения списка методов из среды выполнения, там, как представляется, нет.)
Изменить: Да, я также знаю, что вы вызываете блок обычным способом (bar(7)
;). То, что мне действительно нужно, - это селектор для метода, который я могу подавать в библиотечный код, который не принимает блоки (per-se).
Ответы
Ответ 1
Блоки очень четкого определения - это общая сумма "сообщений", которые блок может получать с точки зрения вызывающих параметров /ABI.
Это происходит по двум причинам:
Во-первых, блок не является функцией, а указатель блока не является указателем на функцию. Они не могут использоваться взаимозаменяемо.
Во-вторых, C ABI таков, что вы должны иметь объявление о начале функции, когда узел вызова компилируется, если параметры должны быть закодированы правильно.
Альтернативой является использование чего-то вроде NSInvocation, которое позволяет кодировать аргументы по отдельности, но даже для этого все еще требуется полное знание C ABI для каждого отдельного аргумента.
В конечном счете, если вы можете скомпилировать сайт вызова, который имеет все параметры, будь то метод Objective-C или вызов функции, верность, необходимая для того, чтобы сделать компилятор счастливым, вы можете преобразовать этот сайт вызова в вызов блок.
т.е. если вы не уточните свой вопрос немного, то, что вы просите, либо уже поддерживается, либо почти невозможно из-за капризов C ABI.
Ответ 2
Вы можете вызвать его как функцию:
bar(7);
В документации есть пример, который использует точно такую же подпись. См. Объявление и использование блока.
Лучшей ссылкой на поведение блоков является документ Block Language Specification (RTF). В этом упоминаются определенные методы, которые поддерживаются (копирование, сохранение и т.д.), Но ничего о методе -invoke
.