Я считаю, что самый быстрый (но несколько грязный) способ сделать это - вызвать objc_msgSend напрямую. Однако вызывать его напрямую опасно, потому что вам нужно прочитать документацию и убедиться, что вы используете правильный вариант для типа возвращаемого значения, а также потому, что objc_msgSend определен как vararg для удобства компилятора, но фактически реализован как клей для быстрой сборки , Вот некоторый код, используемый для вызова метода делегата - [делегат 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. Имейте в виду, что если возвращаемое значение является float или структурой, вам нужно использовать другой вариант objc_msgSend. Наконец, отправьте сообщение, используя тот же механизм, который Objective-C использует под листами.