Objective-C Language Méthodes d'appel directement


Exemple

Si vous avez besoin d'appeler une méthode Objective-C à partir du code C, vous avez deux façons: d'utiliser objc_msgSend ou d'obtenir le pointeur de fonction d'implémentation de méthode ( IMP ) et de l'appeler.

#import <objc/objc.h>

@implementation Example

- (double)negate:(double)value {
    return -value;
}

- (double)invert:(double)value {
    return 1 / value;
}

@end

// Calls the selector on the object. Expects the method to have one double argument and return a double.
double performSelectorWithMsgSend(id object, SEL selector, double value) {
    // We declare pointer to function and cast `objc_msgSend` to expected signature.
    // WARNING: This step is important! Otherwise you may get unexpected results!
    double (*msgSend)(id, SEL, double) = (typeof(msgSend)) &objc_msgSend;

    // The implicit arguments of self and _cmd need to be passed in addition to any explicit arguments.
    return msgSend(object, selector, value);
}

// Does the same as the above function, but by obtaining the method's IMP.
double performSelectorWithIMP(id object, SEL selector, double value) {
    // Get the method's implementation.
    IMP imp = class_getMethodImplementation([self class], selector);

    // Cast it so the types are known and ARC can work correctly.
    double (*callableImp)(id, SEL, double) = (typeof(callableImp)) imp;

    // Again, you need the explicit arguments.
    return callableImp(object, selector, value);
} 

int main() {
    Example *e = [Example new];

    // Invoke negation, result is -4
    double x = performSelectorWithMsgSend(e, @selector(negate:), 4);

    // Invoke inversion, result is 0.25
    double y = performSelectorWithIMP(e, @selector(invert:), 4);
}

objc_msgSend fonctionne en obtenant l'IMP pour la méthode et en l'appelant. Les IMP pour les dernières méthodes appelées sont mises en cache, donc si vous envoyez un message Objective-C dans une boucle très serrée, vous pouvez obtenir des performances acceptables. Dans certains cas, la mise en cache manuelle de l'IMP peut donner des performances légèrement meilleures, même s'il s'agit d'une optimisation de dernier recours.