Mescolando le funzioni C in una class Objective-C

Sto scrivendo una class Objective-C ma usa un’API scritta in C. Questo va benissimo poiché il mixaggio delle chiamate C con chiamate Objective-C causa pochi problemi.

Tuttavia una delle chiamate API richiede un metodo di richiamata (esempio):

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

Dove MyCFHostClientCallBack è una funzione C definita in questo modo:

 static void MyCFHostClientCallBack(CFHostRef host, CFHostInfoType typeInfo, const CFStreamError *error, void *info); 
  1. Come posso chiamare un metodo Objective-C al posto di questo?
  2. Posso / devo mescolare le funzioni C con le mie chiamate Objective-C?
  3. Come faccio a mescolare le funzioni C con i metodi Objective-C?

È ansible utilizzare i metodi di mixaggio C e Objective-C, ecco un semplice esempio che utilizza l’API SQLite all’interno di un’app per iPhone: ( sito del corso )

Scarica il file zip (09_MySQLiteTableView.zip)

Le funzioni C devono essere dichiarate al di fuori della @implementation in un file Objective-C (.m).

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

Poiché la funzione C è al di fuori di @implementation non può chiamare metodi come

 [self doSomething] 

e non ha accesso a Ivars.

Questo può essere risolto finché la funzione call-back accetta un parametro userInfo o di tipo context , normalmente di tipo void* . Questo può essere usato per inviare qualsiasi object Objective-C alla funzione C.

Come nel codice di esempio , questo può essere manipolato con normali operazioni Objective-C.

Inoltre, leggi questa risposta: mescolare le funzioni C in una class Objective-C

Per chiamare il codice Objective-C da un callback in C, vorrei usare qualcosa come:

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

Come posso chiamare un metodo Objective-C al posto di questo?

Non puoi.

Posso / devo mescolare la funzione C con la mia chiamata Objective-C?

Sì. Scrivi una funzione C e usala come richiamo della funzione CF.

Come mescolo la funzione C con i metodi Objective-C?

È ansible impostare l’ self come il puntatore di info nella struttura di contesto. Questo sarà passato al callback. Quindi, nel callback, reindirizza il puntatore alle info su id :

 MyClass *self = (id)info; 

È quindi ansible inviare messaggi self . Non è ancora ansible accedere direttamente alle variabili di istanza, poiché una funzione C è esterna alla sezione @implementation . Dovrai renderli proprietà. Puoi farlo con un’estensione di class . (Contrariamente a quello che dice il documento, non dichiareresti l’estensione all’interno di @implementation , ma nello stesso file con esso, generalmente proprio sopra di esso).

Quello che ho sempre trovato utile in questa situazione è creare un wrapper Obj-C in cima all’API C. Implementa ciò che ti serve per usare le funzioni C e costruisci una class (o due) Objective-C su di essa, in modo che tutto ciò che il mondo esterno vedrà. Ad esempio, nel caso di una richiamata come questa, è ansible creare una funzione C che richiami i metodi delegati Obj-C su altri oggetti.