Wie kann ich mich verhindern, dass versehentlich ein NSNumber der Zeiger zu verwenden, wenn ich seine intValue wollen?

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

Frage

Ein Merkmal von Java, die Ich mag ist Autoboxing, in der der Compiler automatisch konvertiert zwischen Primitiven und deren Wrapper-Klassen.

Ich schreibe eine Core Data-Anwendung in Objective-C / Cocoa, und ich finde es frustrierend zu behandeln meine ganze Zahl programmatisch Attribute. Hier ist der Grund:

//img is a managed object that I have fetched

NSString* filename = [NSString stringWithFormat:@"image%d.png", [[img valueForKey:@"imageID"] intValue]];  

Wenn ich die intValue Nachricht vergessen passieren, die ich manchmal tun, dann ist die int, die stringWithFormat: geben wird ist eigentlich der Zeigerwert.

Das Problem ist, dass dies völlig geräuschlos geschieht - keinen Compiler-Fehler oder Warnung. Manchmal werde ich verbringe viel zu lange das Debuggen, wenn diese dumme, dumme Sache ist das Problem.

Gibt es eine Möglichkeit, meinen Programmierstil oder meine Compiler-Einstellungen zu ändern, mich daran zu hindern, in diesem Fall gefangen zu werden?

Bearbeiten : Ich war über die Tatsache nicht klar, dass das obige Beispiel nur einer von vielen Orten, wo ich in Schwierigkeiten geraten. Hier ist ein weiteres hypothetisches Beispiel, das nicht mit Strings zu tun hat:

Entity CollegeClass hat zwei Integer-Attribute: courseNumber und enrollmentLimit. Lassen Sie uns sagen, dass ich natürlich Zahlen vergleichen wollen:

//classFoo is a NSManagedObjects I've fetched
if ([[classFoo valueForKey@"courseNumber"] intValue] < 400) {
    NSLog(@"undergraduate class");
}

oder ähnlich, nehme ich den durchschnittlichen Einschulungstermin für alle Klassen in der CS-Abteilung berechnen möge.

War es hilfreich?

Lösung

  

... nehme ich den durchschnittlichen Einschulungstermin für alle Klassen in der CS-Abteilung berechnen möge.

Dies ist einfach mit NSArray ist zu tun und NSSet des @avg Operator . Natürlich, das wird eine NSNumber zurückkehren, die 2 Sie zurück in Problem # setzt:

  

Lassen Sie uns sagen, ich will natürlich Zahlen vergleichen:

//classFoo is a NSManagedObjects I've fetched
if ([[classFoo valueForKey@"courseNumber"] intValue] < 400) {
    NSLog(@"undergraduate class");
}

Ich nehme an, Sie bedeuten, dass das Problem, das Sie die intValue Nachricht riskieren wird weggelassen, wodurch die id zum int des NSNumber Objekt verglichen wird.

Der Compiler bietet eine Warnung für solche Vergleiche. In Xcode, fügen -Wextra zu Ihrer „Ander C Flags“ Build-Einstellung. Für weitere Warnung Optionen finden Sie unter die vollständige Liste der GCC Warnungen .

Andere Tipps

Sie können% @ verwenden, um eine NSNumber direkt in eine Zeichenfolge zu konvertieren, anstatt das% d.

Es wird tatsächlich um jeden NSObject basierte Klasse und wandelt es in einen String, glaube ich.

Dies ist nur dann anwendbar, wenn mit Core Data zu tun, aber wenn Sie verwenden MOGenerator Klassen zu erzeugen, für Ihre Core Data-Objekte (was ich empfehlen würde ohnehin tun), können Sie dann -[propertyName]Value Methoden direkt den richtigen Wert für Eigenschaften, die NSNumbers zugreifen zu können zurück:

// These two methods are identical when called on a class 
// which was generated with MOGenerator
[[object imageID] intValue];
[object imageIDValue];

Schalten Sie den „Typecheck ruft printf / scanf“ Warnung, wenn es nicht auf ohnehin schon ist. Dies gilt nicht zur Zeit Hilfe bei der NS / CFString Formatierung, aber ich habe eine Radar-Erweiterungsanfrage (x-Radar: // Problem / 7375186), eingereicht dafür. Gerne können Sie Ihre eigenen, natürlich einzureichen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top