2011-11-07 5 views
8

So che questa domanda è stata posta più volte, ma la mia è leggermente diversa. Prima di chiuderlo come duplicato, leggilo per intero. Ci sono molti messaggi sullo stack overflow che dicono "Personalmente, odio i MACRO, Non usare quella merda". Ho letto tutto questo e il mio caso è diverso. Sto provando a definire gli URL utilizzati in un software (app iOS) usando le macro #define.#define o const string *

Sono d'accordo sul fatto che l'utilizzo di stringhe const sia una pratica migliore di #define macro. Ma in un mondo di API sempre più basato su REST che accetta parametri di query come parte dell'URL, come puoi ancora utilizzare le stringhe const per rappresentare un URL che cambia?

Invece di http://api.myblog.com/posts?entryid=%@ un server API seguenti principi REST avrebbero http://api.blog.com/posts/entries/[entryid]

Nel primo tipo, l'URL è http://api.myblog.com/posts per tutte le voci e non cambiano. Una stringa const era possibile.

In quest'ultimo tipo, l'URL cambia ad ogni voce e io uso una macro che si espande in un URL completo come questo.

#define GET_ENTRY_URL(__MY_ENTRY_ID__) [NSString stringWithFormat:@"http://api.myblog.com/posts/entries/%@", __MY_ENTRY_ID__]; 

Sono presenti difetti di progettazione nel mio metodo? Vorrei conoscere i tuoi dati.

Grazie.

risposta

4

Guardando dal punto di vista del compilatore, #define è una direttiva per il preprocessore (fare riferimento alla definizione in c, http://en.wikipedia.org/wiki/C_preprocessor).

In questo caso, il compilatore potrebbe eseguire l'intera sostituzione del testo prima di compilare i codici.

es .: se si definisce:

#define GET_ENTRY_URL(__MY_ENTRY_ID__) [NSString stringWithFormat:@"http://api.myblog.com/posts/entries/%@", __MY_ENTRY_ID__]; 

Potrebbe essere sostituendo ogni occorrenze di GET_ENTRY_URL (x) con [... NSString, x] nei tuoi codici. Potenzialmente, le istanze potrebbero essere create ovunque utilizziamo la macro se l'implementazione dell'obiettivo-c lo sta seguendo.

const/variabile statico sembra essere un modo migliore.

+0

Come passate le variabili in nsstrings static const? – Mugunth

+1

sai che non puoi, dal momento che è una costante. imho, se l'API diventa più complicata, costruirò una classe come una NSURL, la costruzione dell'URL può essere eseguita all'interno. forse non è ancora fondamentale usare la macro o no, ma quando questo pezzo di codice arriva in molti punti, le cose potrebbero risentirne di nuovo. ad esempio: dividi tutto GET_ENTRY_URL (x) in due GET_CODING_ENTRY_URL (x), GET_PERSONAL_ENTRY_URL (x). – alvinsj

2

Quello che ho fatto nella mia app è stato definire un const per il percorso di base e un const per ogni specifico percorso con i codici di formato di sostituzione all'interno del percorso quando necessario.

NSString const *APIBasePath  = @"http://api.mydomain.com"; 
NSString const *APIEntryPath  = @"/entries/%d"; 
NSString const *APIUpdateEntryPath = @"/entries/%d/update"; 

Ho poi costruire l'URL in fase di esecuzione per ogni API come segue:

- (void)updateEntryNumber:(NSUInteger)entryNumber 
{ 
    NSString *updateEntryPath = [NSString stringWithFormat:APIUpdateEntryPath, entryNumber]; 
    NSString *APIPath = [APIBasePath stringByAppendingPathComponent:updateEntryPath]; 
    // do something 
} 
+0

Ho appena scoperto che 'stringByAppendingPathComponent:' restituisce solo una barra, ad esempio 'http:/...', sembra che questo metodo sia usato per il percorso del file, non per l'url. Invece, io uso 'stringByAppendingString:'. :) – Kjuly