NSInteger myInt = 1804809223;
NSLog(@"%i", myInt); <====
Der obige Code erzeugt einen Fehler:
Werte vom Typ 'NSInteger' sollten nicht als Formatargumente verwendet werden. Fügen Sie stattdessen 'explizit' eine explizite Besetzung hinzu
Die korrigierte NSLog
Nachricht ist tatsächlich NSLog(@"%lg", (long) myInt);
. Warum muss ich den ganzzahligen Wert von in konvertieren myInt
, long
wenn der Wert angezeigt werden soll?
objective-c
xcode
casting
nsinteger
Daniel Lee
quelle
quelle
NSLog(@"%ld", (long) myInt);
, daslong
gegossen wird, um es mit dem oben zu machen Matchl
Qualifier%ld
, aber all das ist nicht notwendig , daNSLog(@"%d", myInt);
ausreichend ist (vorausgesetzt , dass wir sehen können , dassmyInt
nichtlong
. Unterm Strich, werfen SiemyInt
bei Verwendung von langen Qualifikationsspiel in Format Zeichenfolge, aber keine Notwendigkeit, entweder langes Zeichenfolgenformat-Qualifikationsmerkmal zu verwenden oderlong
hierNSInteger
ist nicht lang), aber es hört sich so an, als würden Sie mit dem OS X-Ziel kompilieren (woNSInteger
istlong
).Antworten:
Sie erhalten diese Warnung, wenn Sie unter OS X (64-Bit) kompilieren, da auf dieser Plattform eine 64-Bit-Ganzzahl
NSInteger
definiertlong
ist. Das%i
Format ist dagegen fürint
32-Bit. Das Format und der tatsächliche Parameter stimmen also nicht in der Größe überein.Da
NSInteger
es sich je nach Plattform um 32-Bit oder 64-Bit handelt, empfiehlt der Compiler,long
allgemein eine Umwandlung hinzuzufügen .Update: Da iOS 7 jetzt auch 64-Bit unterstützt, können Sie beim Kompilieren für iOS dieselbe Warnung erhalten.
quelle
NSLog(@"%ld", (long) myInt)
, funktioniert es auf 32-Bit und 64-Bit korrekt.long myInt = [myNumber longValue];
. Viele (Core) Foundation-Methoden verwenden jedoch NS (U) Integer als Parameter oder Rückgabewert, sodass das allgemeine Problem weiterhin besteht. In Ihrer App kann es auch sinnvoll sein, NS (U) Integer zu verwenden, um einen größeren verfügbaren Bereich auf 64-Bit-Geräten zu erhalten.Sie müssen nichts umwandeln, wenn Ihre Formatspezifizierer Ihren Datentypen entsprechen. In der Antwort von Martin R finden Sie Details dazu, wie
NSInteger
in Bezug auf native Typen definiert wird.Für Code, der für 64-Bit-Umgebungen erstellt werden soll, können Sie Ihre Protokollanweisungen wie folgt schreiben:
In 32-Bit-Umgebungen können Sie Folgendes schreiben:
und es wird alles ohne Abgüsse funktionieren.
Ein Grund für die Verwendung von Casts ist, dass guter Code in der Regel plattformübergreifend portiert wird. Wenn Sie Ihre Variablen explizit umwandeln, wird er sauber auf 32- und 64-Bit kompiliert:
Beachten Sie, dass dies nicht nur für NSLog-Anweisungen gilt, die schließlich nur Debugging-Hilfsmittel sind, sondern auch für
[NSString stringWithFormat:]
und die verschiedenen abgeleiteten Nachrichten, die legitime Elemente des Produktionscodes sind.quelle
Anstatt eine NSInteger an NSLog zu übergeben, übergeben Sie einfach eine NSNumber. Dadurch werden alle Casts umgangen und der richtige String-Format-Bezeichner ausgewählt.
Es funktioniert auch für NSUIntegers, ohne sich darum kümmern zu müssen. Siehe Antwort auf NSInteger und NSUInteger in einer gemischten 64-Bit / 32-Bit-Umgebung
quelle
Während der Verwendung bleibt die Warnung erhalten, die Warnung
NSLog(@"%ld", (long)myInt);
wird jedoch nach der Änderungsdeklarationlong myInt = 1804809223;
in iOS 10 beendet.quelle
OS X verwendet verschiedene Datentypen - NSInteger, NSUInteger, CGFloat und CFIndex -, um eine konsistente Darstellung von Werten in 32- und 64-Bit-Umgebungen bereitzustellen. In einer 32-Bit-Umgebung werden NSInteger und NSUInteger als int bzw. unsigned int definiert. In 64-Bit-Umgebungen werden NSInteger und NSUInteger als long bzw. unsigned long definiert. Um zu vermeiden, dass je nach Plattform unterschiedliche Druckspezifizierer vom Typ printf verwendet werden müssen, können Sie die in diesem Link gezeigten Spezifizierer sowohl für 32-Bit- als auch für 64-Bit-Umgebungen verwenden.
quelle