Mezcla de funciones C en una clase Objective-C

Estoy escribiendo una clase Objective-C pero usa una API escrita en C. Esto es bastante bueno ya que mezclar llamadas C con llamadas Objective-C causa pocos problemas.

Sin embargo, una de las llamadas API requiere un método de callback (ejemplo):

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

Donde MyCFHostClientCallBack es una función C definida así:

 static void MyCFHostClientCallBack(CFHostRef host, CFHostInfoType typeInfo, const CFStreamError *error, void *info); 
  1. ¿Puedo / Cómo puedo llamar un método Objective-C en lugar de esto?
  2. ¿Puedo / debo mezclar funciones C con mis llamadas a Objective-C?
  3. ¿Cómo mezclo las funciones C con los métodos Objective-C?

Es posible combinar los métodos C y Objective-C y la función, aquí hay un ejemplo simple que usa la API SQLite dentro de una aplicación para iPhone: ( sitio del curso )

Descargue el archivo Zip (09_MySQLiteTableView.zip)

Las funciones C deben declararse fuera de @implementation en un archivo Objective-C (.m).

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

Como la función C está fuera de @implementation no puede invocar métodos como

 [self doSomething] 

y no tiene acceso a ivars.

Esto puede userInfo siempre que la función de callback tome un userInfo o tipo de context , normalmente de tipo void* . Esto se puede usar para enviar cualquier objeto Objective-C a la función C.

Como en el código de ejemplo , esto puede ser manipulado con operaciones Objective-C normales.

Además, lea esta respuesta: Mezcla de funciones C en una clase Objective-C

Para llamar al código Objective-C desde una callback C, usaría algo como:

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

¿Puedo / Cómo puedo llamar un método Objective-C en lugar de esto?

No puedes.

¿Puedo / debo mezclar la función C con mi llamada a Objective-C?

Sí. Escriba una función C y utilícela como callback a la función CF.

¿Cómo mezclo la función C con los métodos Objective-C?

Puede establecerse como el puntero de info en su estructura de contexto. Eso se pasará a la callback. Luego, en la callback, vuelve a id puntero de info a la id :

 MyClass *self = (id)info; 

A continuación, puede enviar mensajes self . Sin embargo, todavía no puede acceder directamente a las variables de instancia, ya que una función C está fuera de la sección @implementation . Tendrás que hacerles propiedades. Puedes hacer esto con una extensión de clase . (Contrariamente a lo que dice el documento, no declararías la extensión dentro de @implementation , sino en el mismo archivo con ella, generalmente justo arriba).

Lo que siempre he encontrado útil en esta situación es crear un contenedor Obj-C sobre la API C. Implemente lo que necesita para usar las funciones C, y construya una clase Objective-C (o dos) encima, de modo que eso sea todo lo que verá el mundo exterior. Por ejemplo, en el caso de una callback como esta, puede crear una función C que llame a métodos delegates Obj-C en otros objetos.