Mélange de fonctions C dans une classe Objective-C

J’écris une classe Objective-C, mais elle utilise une API écrite en C. C’est généralement très bien, car le mélange d’appels C avec des appels Objective-C pose peu de problèmes.

Toutefois, l’un des appels d’API nécessite une méthode de rappel (exemple):

success = CFHostSetClient(host, MyCFHostClientCallBack, &context); 

MyCFHostClientCallBack est une fonction C définie comme suit:

 static void MyCFHostClientCallBack(CFHostRef host, CFHostInfoType typeInfo, const CFStreamError *error, void *info); 
  1. Comment puis-je appeler une méthode Objective-C à la place de cela?
  2. Puis-je / dois-je mélanger des fonctions C avec mes appels Objective-C?
  3. Comment mélanger des fonctions C avec des méthodes Objective-C?

    Il est possible de mélanger des méthodes et des fonctions C et Objective-C. Voici un exemple simple d’utilisation de l’API SQLite dans une application iPhone: ( site du cours )

    Téléchargez le fichier Zip (09_MySQLiteTableView.zip)

    Les fonctions C doivent être déclarées en dehors de @implementation dans un fichier Objective-C (.m).

     int MyCFunction(int num, void *data) { //code here... } @implementation - (void)MyObjectiveCMethod:(int)number withData:(NSData *)data { //code here } @end 

    Comme la fonction C est en dehors de @implementation elle ne peut pas appeler des méthodes telles que

     [self doSomething] 

    et n’a pas access aux ivars.

    Cela peut être contourné tant que la fonction de userInfo prend un userInfo ou de type context , normalement de type void* . Ceci peut être utilisé pour envoyer n’importe quel object Objective-C à la fonction C.

    Comme dans l’ exemple de code , cela peut être manipulé avec des opérations Objective-C normales.

    De plus, veuillez lire la réponse suivante: Mélange de fonctions C dans une classe Objective-C

    Pour appeler le code Objective-C à partir d’un rappel C, je voudrais utiliser quelque chose comme:

     void * refToSelf; int cCallback() { [refToSelf someMethod:someArg]; } @implementation SomeClass - (id) init { self = [super init]; refToSelf = self; } - (void) someMethod:(int) someArg { } 

    Comment puis-je appeler une méthode Objective-C à la place de cela?

    Vous ne pouvez pas.

    Puis-je / dois-je mélanger la fonction C avec mon appel Objective-C?

    Oui. Ecrivez une fonction C et utilisez-la comme rappel à la fonction CF.

    Comment mélanger la fonction C avec les méthodes Objective-C?

    Vous pouvez définir vous- self comme pointeur d’ info dans votre structure de contexte. Cela sera transmis au rappel. Ensuite, dans le rappel, remettez le pointeur d’ info sur id :

     MyClass *self = (id)info; 

    Vous pouvez ensuite envoyer self messages personnels. Cependant, vous ne pouvez toujours pas accéder directement aux variables d’instance, car une fonction C est en dehors de la section @implementation . Vous devrez les rendre propriétés. Vous pouvez le faire avec une extension de classe . (Contrairement à ce que dit ce document, vous ne déclareriez pas l’extension dans @implementation , mais dans le même fichier avec elle, généralement juste au-dessus de celle-ci.)

    Ce que j’ai toujours trouvé utile dans cette situation est de créer un wrapper Obj-C en plus de l’API C. Implémentez ce dont vous avez besoin pour utiliser les fonctions C et construisez une classe Objective-C (ou deux) par dessus, afin que tout le monde extérieur puisse le voir. Par exemple, dans le cas d’un rappel comme celui-ci, vous pouvez créer une fonction C qui appelle des méthodes de délégation Obj-C sur d’autres objects.