Domanda

Sto scrivendo una classe Objective-C ma utilizza un'API scritta in C. Questo va principalmente bene poiché la combinazione di 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. Can / 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 mescolo le funzioni C con i metodi Objective-C?
È stato utile?

Soluzione

È possibile combinare metodi e funzioni 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 del @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 del @implementation non può chiamare metodi come

[self doSomething]

e non ha accesso agli ivar.

Questo può essere risolto fintanto che la funzione di richiamata accetta un parametro di tipo userInfo o context , normalmente di tipo void * . Può essere utilizzato per inviare qualsiasi oggetto Objective-C alla funzione C.

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

Inoltre, leggi questa risposta: Mixing C funzioni in una classe Objective-C

Altri suggerimenti

Per chiamare il codice Objective-C da un callback C, dovrei usare qualcosa del tipo:

void * refToSelf;
int cCallback()
{
    [refToSelf someMethod:someArg];
}

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

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

Non puoi.

  

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

Sì. Scrivi una funzione C e usala come callback per la funzione CF.

  

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

Puoi impostare self come puntatore info nella struttura del tuo contesto. Questo verrà passato al callback. Quindi, nel callback, reindirizzare il puntatore info su id :

MyClass *self = (id)info;

È quindi possibile inviare messaggi self . Tuttavia, non è ancora possibile accedere direttamente alle variabili di istanza, poiché una funzione C è al di fuori della sezione @implementation . Dovrai renderli proprietà. Puoi farlo con un'estensione di classe a>. (Contrariamente a quanto dice quel documento, non dichiareresti l'estensione all'interno di @implementation , ma nello stesso file con esso, generalmente proprio sopra di esso.)

Ciò che ho sempre trovato utile in questa situazione è creare un wrapper Obj-C in cima all'API C. Implementa ciò di cui hai bisogno per utilizzare le funzioni C e crea una classe C (o due) Objective-C su di essa, in modo che tutto ciò che il mondo esterno vedrà. Ad esempio, nel caso di un callback come questo, è possibile creare una funzione C che chiama i metodi delegati Obj-C su altri oggetti.

scroll top