Я считаю, что самый быстрый (но несколько грязный) способ сделать это - напрямую вызвать objc_msgSend. Однако вызывать его напрямую опасно, потому что вам нужно прочитать документацию и убедиться, что вы используете правильный вариант для типа возвращаемого значения, и потому что objc_msgSend определен как vararg для удобства компилятора, но фактически реализован как клей для быстрой сборки . Вот код, используемый для вызова метода делегата - [delegate integerDidChange:], который принимает единственный целочисленный аргумент.
#import <objc/message.h>
SEL theSelector = @selector(integerDidChange:);
if ([self.delegate respondsToSelector:theSelector])
{
typedef void (*IntegerDidChangeFuncPtrType)(id, SEL, NSInteger);
IntegerDidChangeFuncPtrType MyFunction = (IntegerDidChangeFuncPtrType)objc_msgSend;
MyFunction(self.delegate, theSelector, theIntegerThatChanged);
}
Это сначала сохраняет селектор, так как мы будем ссылаться на него несколько раз, и было бы легко допустить опечатку. Затем он проверяет, действительно ли делегат отвечает на селектор - это может быть дополнительный протокол. Затем он создает тип указателя функции, который указывает фактическую сигнатуру селектора. Имейте в виду, что все сообщения Objective-C имеют два скрытых первых аргумента: отправляемый объект и отправляемый селектор. Затем мы создаем указатель функции соответствующего типа и устанавливаем его так, чтобы он указывал на базовую функцию objc_msgSend. Имейте в виду, что если возвращаемое значение - это число с плавающей запятой или структура, вам нужно использовать другой вариант objc_msgSend. Наконец, отправьте сообщение, используя тот же механизм, который Objective-C использует под листами.