J'écris une classe Objective-C mais elle utilise une API écrite en C. C'est très bien car le mélange d'appels C avec des appels Objective-C provoque peu de problèmes.
Cependant, l'un des appels API nécessite une méthode de rappel (exemple):
success = CFHostSetClient(Host, MyCFHostClientCallBack, &context);
Où MyCFHostClientCallBack
est une fonction C définie comme ceci:
static void MyCFHostClientCallBack(CFHostRef Host, CFHostInfoType typeInfo, const CFStreamError *error, void *info);
Mélanger les méthodes et les fonctions C et Objective-C est possible, voici un exemple simple qui utilise 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
Parce que la fonction C est en dehors du @implementation
il ne peut pas appeler des méthodes comme
[self doSomething]
et n'a pas accès aux ivars.
Cela peut être contourné tant que la fonction de rappel prend un paramètre de type userInfo
ou context
, normalement de type void*
. Cela 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 des opérations Objective-C normales.
De plus, veuillez lire cette réponse: Mélanger les fonctions C dans une classe Objective-C
Pour appeler du code Objective-C à partir d'un rappel C, j'utiliserais 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/comment 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. Écrivez une fonction C et utilisez-la comme rappel de la fonction CF.
Comment mélanger la fonction C avec les méthodes Objective-C?
Vous pouvez définir self
comme pointeur info
dans votre structure de contexte. Cela sera transmis au rappel. Ensuite, dans le rappel, redéfinissez le pointeur info
sur 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 @implementation
section. Vous devrez en faire des 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 à l'intérieur de @implementation
, mais dans le même fichier, généralement juste au-dessus.)
Ce que j'ai toujours trouvé utile dans cette situation, c'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 créez une classe Objective-C (ou deux) par-dessus, afin que tout le monde extérieur le voie. 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.