Подтвердить что ты не робот

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).

4b9b3361

Ответ 1

Блоки очень четкого определения - это общая сумма "сообщений", которые блок может получать с точки зрения вызывающих параметров /ABI.

Это происходит по двум причинам:

Во-первых, блок не является функцией, а указатель блока не является указателем на функцию. Они не могут использоваться взаимозаменяемо.

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

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

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

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

Ответ 2

Вы можете вызвать его как функцию:

bar(7);

В документации есть пример, который использует точно такую ​​же подпись. См. Объявление и использование блока.

Лучшей ссылкой на поведение блоков является документ Block Language Specification (RTF). В этом упоминаются определенные методы, которые поддерживаются (копирование, сохранение и т.д.), Но ничего о методе -invoke.