NSInteger myInt = 1804809223;
NSLog(@"%i", myInt); <====
Kode di atas menghasilkan kesalahan:
Nilai tipe 'NSInteger' tidak boleh digunakan sebagai format argumen; tambahkan cast eksplisit ke 'long' sebagai gantinya
NSLog
Pesan yang dikoreksi sebenarnya NSLog(@"%lg", (long) myInt);
. Mengapa saya harus mengonversi nilai integer myInt
menjadi long
jika saya ingin nilai ditampilkan?
objective-c
xcode
casting
nsinteger
Daniel Lee
sumber
sumber
NSLog(@"%ld", (long) myInt);
, paralong
pemain harus membuatnya sesuai denganl
kualifikasi%ld
, tetapi semua itu tidak perlu karenaNSLog(@"%d", myInt);
cukup (mengingat bahwa kita dapat melihat bahwamyInt
tidaklong
. Intinya, AndamyInt
menggunakan jika menggunakan kualifikasi panjang dalam format string, tetapi tidak perlu menggunakan kualifikasi format string panjang ataulong
dilemparkan ke siniNSInteger
yang tidak lama), tapi kedengarannya seperti Anda kompilasi target OS X (di manaNSInteger
adalahlong
).Jawaban:
Anda mendapatkan peringatan ini jika Anda mengkompilasi pada OS X (64-bit), karena pada platform
NSInteger
itu didefinisikan sebagailong
dan adalah integer 64-bit. The%i
Format, di sisi lain, adalah untukint
, yang 32-bit. Jadi format dan parameter aktual tidak sesuai ukurannya.Karena
NSInteger
32-bit atau 64-bit, tergantung pada platform, kompiler merekomendasikan untuk menambahkan gipslong
secara umum.Pembaruan: Karena iOS 7 sekarang mendukung 64-bit juga, Anda bisa mendapatkan peringatan yang sama saat mengkompilasi untuk iOS.
sumber
NSLog(@"%ld", (long) myInt)
, ia bekerja pada 32-bit dan 64-bit dengan benar.long myInt = [myNumber longValue];
. Tetapi banyak (Core) metode Foundation menggunakan NS (U) Integer sebagai parameter atau nilai kembali, sehingga masalah umum tetap ada. Juga masuk akal di aplikasi Anda untuk menggunakan NS (U) Integer untuk mendapatkan jangkauan yang lebih besar pada perangkat 64-bit.Anda tidak perlu melakukan apa pun jika specifier format Anda cocok dengan tipe data Anda. Lihat jawaban Martin R untuk perincian tentang bagaimana
NSInteger
didefinisikan dalam hal jenis asli.Jadi untuk kode yang dimaksudkan untuk dibangun untuk lingkungan 64-bit, Anda dapat menulis pernyataan log Anda seperti ini:
sedangkan untuk lingkungan 32-bit Anda dapat menulis:
dan itu semua akan bekerja tanpa gips.
Salah satu alasan untuk menggunakan gips adalah karena kode yang baik cenderung untuk porting di seluruh platform, dan jika Anda melemparkan variabel Anda secara eksplisit itu akan dikompilasi dengan bersih pada 32 dan 64 bit:
Dan perhatikan ini benar bukan hanya untuk pernyataan NSLog, yang hanya merupakan alat bantu debugging, tetapi juga untuk
[NSString stringWithFormat:]
dan berbagai pesan turunan, yang merupakan elemen sah dari kode produksi.sumber
Alih-alih meneruskan NSInteger ke NSLog, hanya meneruskan NSNumber. Ini akan berkeliling semua gips dan memilih specifier format string yang tepat.
Ini juga berfungsi untuk NSUIntegers tanpa harus khawatir tentang itu. Lihat jawaban untuk NSInteger dan NSUInteger dalam lingkungan campuran 64bit / 32bit
sumber
Itu terus peringatan saat menggunakan
NSLog(@"%ld", (long)myInt);
, tetapi berhenti peringatan setelah mengubah deklarasi kelong myInt = 1804809223;
di iOS 10.sumber
OS X menggunakan beberapa tipe data — NSInteger, NSUInteger, CGFloat, dan CFIndex — untuk menyediakan cara yang konsisten dalam merepresentasikan nilai dalam lingkungan 32-dan 64-bit. Dalam lingkungan 32-bit, NSInteger dan NSUInteger didefinisikan sebagai int dan unsigned int, masing-masing. Dalam lingkungan 64-bit, NSInteger dan NSUInteger masing-masing didefinisikan sebagai panjang dan tidak bertanda. Untuk menghindari perlunya menggunakan specifier tipe gaya printf yang berbeda tergantung pada platform, Anda dapat menggunakan specifier yang ditunjukkan dalam tautan ini untuk lingkungan 32 bit dan 64 bit.
sumber