Objective-C: есть ли -invoke для блоков, которые принимают параметры? - PullRequest
11 голосов
/ 20 сентября 2011

Как вы, наверное, знаете, блоки занимают -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 для извлечения списка методов из среды выполнения; похоже, их нет.)

Редактировать: Да, я также осведомлен о том, чтобы вызывать блок обычным способом (bar(7);).Что мне действительно нужно, так это селектор метода, который я могу вставить в библиотечный код, который не принимает блоки (per se).

Ответы [ 2 ]

11 голосов
/ 20 сентября 2011

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

bar(7);

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

Лучшим справочным материалом о поведении блоков является документ Спецификация языка блоков (RTF).Здесь упоминаются определенные методы, которые поддерживаются (копирование, сохранение и т. Д.), Но ничего о методе -invoke.

5 голосов
/ 20 сентября 2011

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

Это по нескольким причинам:

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

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

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

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

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

...