2012-02-01 4 views
6

Ho lavorato a un progetto iOS da qualche tempo e di recente ho deciso di portare il codice su un progetto Mac. Poiché ho scelto di utilizzare NSInteger nel mio codice e NSInteger è un typecast dipendente dall'ambiente, significa che le mie variabili sono di diverso tipo nelle app iOS e Mac.Quando si passa a Mac da iOS nello sviluppo Objective-C, NSIntegers fornisce errori di corrispondenza di tipo

Quando eseguo la suite di test su Mac, tutte le mie STAssertEquals le chiamate con l'errore "Tipo non corrispondente -" perché i tipi non corrispondono:

NSInteger foo = 1; 
STAssertEquals(foo, 1, nil); // Test fails!! 

Typecasting miei scalari sembra funzionare, ma questo sembra davvero disordinato:

NSInteger foo = 1; 
STAssertEquals(foo, (NSInteger)1, nil); // Succeeds, but is ugly!! 

Mi manca qualcosa qui? Sto iniziando a sospettare che la decisione di utilizzare NSIntegers sia stata una scelta sbagliata.

Aggiornamento: Forse this article è correlato. Sembra supportare gli scalari di typecasting.

risposta

5

L'utilizzo di NSInteger è probabilmente la scelta giusta, ma causa alcuni problemi con STAssertEquals.

STAssertEquals fallisce se i due oggetti hanno differenti Objective-C type encodings

A soli 1 saranno interpretati dal compilatore C come (int firmato), che ha tipo di codifica "i".

Queste macro sarebbe anche fallire:

unsigned u = 1; 
STAssertEquals(u, 1, nil); // Fails because u is type "I" (unsigned int) and 1 is type "i" (int) 

char c = 1; 
STAssertEquals(c, 1, nil); // Fails because c is type "c" (signed char) and 1 is type "i" (signed int) 

per rendere il compilatore utilizzare un tipo diverso per 1, si dovrebbe aggiungere un suffisso, come 1U per (unsigned int), 1UL per (unsigned long) o 1L per molto tempo).

NSInteger viene definito con le stesse dimensioni dei puntatori, che dipende dall'architettura del dispositivo. Su Mac OS X a 32 bit e iOS, NSInteger è di tipo (signed int) o "i". Su Mac OS X a 64 bit, è di tipo long o "q". (64-bit Mac OS X è un'architettura LP64, il che significa che L ongs e P ointers sono entrambi -bits larghezza)

Così, il lato sinistro del STAssertEquals è un "q" , mentre il lato destro è "i", causando la mancata corrispondenza del tipo.

La soluzione di utilizzare (NSInteger) 1 sembra rappresentare con precisione ciò che si desidera - testare una variabile NSInteger contro una costante NSInteger di valore 1.

+0

Vorrei assumere la seguente idea sarebbe quasi certamente male, ma ho pensato di chiedere : Esiste un modo per forzare il compilatore a trattare scalari non tipizzati come "1" come NSIntegers? –

+1

Non ci credo. Il compilatore promuoverà una costante di interi considerevolmente grande per un (firmato lungo) o (firmato lungo lungo), ma non credo che ci sia un modo per ottenere questo comportamento gratuitamente (anche se ci fosse, probabilmente non vorresti fare quello :)) – iccir

Problemi correlati