Mélange de fonctions C dans une classe Objective-C
-
03-07-2019 - |
Question
Je suis en train d'écrire 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);
Où MyCFHostClientCallBack
est une fonction C définie comme suit:
static void MyCFHostClientCallBack(CFHostRef host, CFHostInfoType typeInfo, const CFStreamError *error, void *info);
- Puis-je appeler une méthode Objective-C à la place?
- Puis-je / dois-je mélanger des fonctions C avec mes appels Objective-C?
- Comment mélanger les fonctions C avec les méthodes Objective-C?
La solution
Il est possible de mélanger les méthodes et les 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 du @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
La fonction C étant en dehors de @implementation
, elle ne peut pas appeler des méthodes telles que
[self doSomething]
et n'a pas accès aux ivars.
Ceci peut être contourné tant que la fonction de rappel prend un paramètre de type userInfo
ou context
, normalement de type void *
. Ceci peut être utilisé pour envoyer n’importe quel objet Objective-C à la fonction C.
Comme dans le exemple de code , cela peut être manipulé avec les opérations normales Objective-C.
De plus, veuillez lire la réponse suivante: Mixage C fonctions dans une classe Objective-C
Autres conseils
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
{
}
Puis-je appeler une méthode Objective-C à la place de cette méthode?
Vous ne pouvez pas.
Puis-je / dois-je mélanger la fonction C avec mon appel à Objective-C?
Oui. Écrivez 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 self
en tant que pointeur info
dans votre structure de contexte. Cela sera transmis au rappel. Ensuite, dans le rappel, transformez le pointeur info
en id
:
MyClass *self = (id)info;
Vous pouvez ensuite envoyer des messages self
. 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 un extension de classe . (Contrairement à ce que dit le document, vous ne déclareriez pas l'extension à l'intérieur de @implementation
, mais dans le même fichier qui le contient, généralement juste au-dessus.)
Ce que j'ai toujours trouvé utile dans cette situation est de créer un wrapper Obj-C au-dessus 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 objets.