Uważam, że najszybszym (ale nieco brudnym) sposobem na to jest bezpośrednie wywołanie objc_msgSend. Jednak wywołanie go bezpośrednio jest niebezpieczne, ponieważ musisz przeczytać dokumentację i upewnić się, że używasz prawidłowego wariantu dla typu wartości zwracanej, a ponieważ objc_msgSend jest zdefiniowany jako vararg dla wygody kompilatora, ale w rzeczywistości jest zaimplementowany jako szybki klej montażowy . Oto kod używany do wywołania metody delegata - [delegate integerDidChange:], która przyjmuje pojedynczy argument będący liczbą całkowitą.
#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);
}
Najpierw zapisuje selektor, ponieważ będziemy odwoływać się do niego wiele razy i łatwo byłoby wprowadzić literówkę. Następnie sprawdza, czy delegat faktycznie odpowiada selektorowi - może to być protokół opcjonalny. Następnie tworzy typ wskaźnika funkcji, który określa rzeczywistą sygnaturę selektora. Należy pamiętać, że wszystkie komunikaty Objective-C mają dwa ukryte pierwsze argumenty, wysyłany obiekt i wysyłany selektor. Następnie tworzymy wskaźnik funkcji odpowiedniego typu i ustawiamy go tak, aby wskazywał na podstawową funkcję objc_msgSend. Pamiętaj, że jeśli zwracana wartość jest zmiennoprzecinkową lub strukturą, musisz użyć innego wariantu objc_msgSend. Na koniec wyślij wiadomość za pomocą tej samej maszyny, której używa Objective-C pod arkuszami.