Come posso impedire me stesso accidentalmente utilizzando il puntatore di un NSNumber quando voglio la sua intValue?
-
19-09-2019 - |
Domanda
Una caratteristica di Java che mi piace molto è autoboxing, in cui il compilatore converte automaticamente tra primitivi e le loro classi wrapper.
Sto scrivendo una domanda di Core Data in Objective-C / Cocoa, e mi sto trovando frustrante per affrontare il mio intero attributi di programmazione. Ecco perché:
//img is a managed object that I have fetched
NSString* filename = [NSString stringWithFormat:@"image%d.png", [[img valueForKey:@"imageID"] intValue]];
Se mi capita di dimenticare il messaggio intValue
, che a volte mi faccio, allora int che viene passato al stringWithFormat:
è in realtà il valore del puntatore.
Il problema è che questo avviene totalmente in silenzio - nessun errore di compilazione o di avvertimento. A volte Passerò troppo tempo il debug quando questo stupido, cosa stupida è il problema.
C'è un modo per cambiare il mio stile di programmazione o le impostazioni del compilatore per impedirmi di impigliarsi in questa trappola?
Modifica : non sono stato chiaro circa il fatto che l'esempio di cui sopra è solo uno dei tanti luoghi in cui mi imbatto in difficoltà. Ecco un altro esempio ipotetico che non ha a che fare con le stringhe:
Entity CollegeClass
ha due attributi intero: courseNumber
e enrollmentLimit
. Diciamo che voglio mettere a confronto numeri dei corsi:
//classFoo is a NSManagedObjects I've fetched
if ([[classFoo valueForKey@"courseNumber"] intValue] < 400) {
NSLog(@"undergraduate class");
}
In alternativa allo stesso modo, supponiamo che io voglio calcolare il limite medio di iscrizione per tutte le classi nel reparto CS.
Soluzione
... suppongo che voglio calcolare il limite medio di iscrizione per tutte le classi nel reparto CS.
Questo è facile da fare con NSArray di e l'operatore @avg
di NSSet . Naturalmente, che restituirà un NSNumber, che vi pone nel problema # 2:
Diciamo che voglio mettere a confronto numeri dei corsi:
//classFoo is a NSManagedObjects I've fetched if ([[classFoo valueForKey@"courseNumber"] intValue] < 400) { NSLog(@"undergraduate class"); }
Presumo che significa che il problema si rischia è omettendo il messaggio intValue
, confrontando così id
dell'oggetto NSNumber al int
.
Il compilatore offre un avvertimento per tali confronti. In Xcode, aggiungere -Wextra
alla vostra impostazione costruire “Altri C Flags”. Per ulteriori opzioni di avviso, vedere l'elenco completo degli avvisi GCC .
Altri suggerimenti
È possibile utilizzare% @ per convertire un NSNumber direttamente a una stringa invece del% d.
Sarà effettivamente prendere qualsiasi NSObject classe basata e convertirlo in una stringa credo.
Questo è applicabile solo quando si tratta di Core Data, ma se si utilizza MOGenerator per generare classi per oggetti vostri dati core (che mi consiglia di fare in ogni caso), è possibile utilizzare i metodi -[propertyName]Value
per accedere direttamente il valore corretto per le proprietà che restituiscono NSNumber
s:
// These two methods are identical when called on a class
// which was generated with MOGenerator
[[object imageID] intValue];
[object imageIDValue];
Attiva l'avviso “TYPECHECK chiama a printf
/ scanf
”, se non è già acceso. Ciò non Al momento aiuto con la formattazione NS / CFString, ma ho presentato una richiesta di miglioramento del radar (x-radar: // problema / 7.375.186) per questo. Sei libero di depositare la propria, ovviamente.