Come posso impedire me stesso accidentalmente utilizzando il puntatore di un NSNumber quando voglio la sua intValue?

StackOverflow https://stackoverflow.com/questions/1898091

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.

È stato utile?

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 NSNumbers:

// 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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top