Kapan saya harus menggunakan NSInteger
vs. int saat mengembangkan untuk iOS? Saya melihat dalam kode sampel Apple yang mereka gunakan NSInteger
(atau NSUInteger
) ketika meneruskan nilai sebagai argumen ke suatu fungsi atau mengembalikan nilai dari suatu fungsi.
- (NSInteger)someFunc;...
- (void)someFuncWithInt:(NSInteger)value;...
Tetapi dalam suatu fungsi mereka hanya menggunakan int
untuk melacak nilai
for (int i; i < something; i++)
...
int something;
something += somethingElseThatsAnInt;
...
Saya telah membaca (diberi tahu) bahwa NSInteger
ini adalah cara yang aman untuk mereferensikan integer baik dalam lingkungan 64-bit atau 32-bit jadi mengapa menggunakan int
sama sekali?
sumber
int
akan lebih cocok bahkanlong
. Mungkin Anda tahu bahwa itu tidak akan melebihi rentang tertentu, dan karena itu berpikir itu akan lebih efisien menggunakan memori sajaint
.NSInteger
adalah memberikan nilai ke dan dari API yang menentukannya. Selain itu tidak memiliki keunggulan dibandingkan int atau panjang. Setidaknya dengan int atau lama Anda tahu penentu format apa yang harus digunakan dalam printf atau pernyataan serupa.Kenapa pakai
int
sama sekali?Apple menggunakan
int
karena untuk variabel kontrol loop (yang hanya digunakan untuk mengontrol iterasi loop)int
datatype baik-baik saja, baik dalam ukuran datatype dan dalam nilai-nilai yang dapat disimpan untuk loop Anda. Tidak perlu untuk tipe data platform bergantung di sini. Untuk variabel kontrol loop bahkan 16-bitint
akan melakukan sebagian besar waktu.Apple menggunakan
NSInteger
nilai pengembalian fungsi atau argumen fungsi karena dalam hal ini datatype [size] penting , karena apa yang Anda lakukan dengan suatu fungsi adalah mengkomunikasikan / meneruskan data dengan program lain atau dengan potongan kode lainnya; lihat jawaban untuk Kapan saya harus menggunakan NSInteger vs int?dalam pertanyaan Anda sendiri ...sumber
OS X adalah "LP64". Ini berarti:
int
selalu 32-bit.long long
selalu 64-bit.NSInteger
danlong
selalu berukuran pointer. Itu berarti mereka 32-bit pada sistem 32-bit, dan 64 bit pada sistem 64-bit.Alasan NSInteger ada adalah karena banyak API lawas yang digunakan secara salah
int
alih-alihlong
menahan variabel ukuran pointer, yang berarti bahwa API harus berubah dariint
kelong
dalam versi 64-bit mereka. Dengan kata lain, API akan memiliki tanda tangan fungsi yang berbeda tergantung pada apakah Anda mengkompilasi arsitektur 32-bit atau 64-bit.NSInteger
bermaksud untuk menutupi masalah ini dengan API lawas ini.Dalam kode baru Anda, gunakan
int
jika Anda memerlukan variabel 32-bit,long long
jika Anda membutuhkan integer 64-bit, danlong
atauNSInteger
jika Anda memerlukan variabel berukuran pointer.sumber
int32_t
. Jika Anda membutuhkan penggunaan integer 64-bitint64_t
. Jika Anda membutuhkan penggunaan variabel berukuran pointerintptr_t
.<stdint.h>
jenis ada untuk tujuan itu.LP64
itu tidak menjamin bahwa itulong long
adalah 64 bit. SebuahLP64
platform dapat memilih untuk memilikilong long
integer 128 bit.Jika Anda menggali implementasi NSInteger:
Sederhananya, typedef NSInteger melakukan langkah untuk Anda: jika arsitekturnya 32-bit, ia menggunakan
int
, jika 64-bit, ia menggunakanlong
. Menggunakan NSInteger, Anda tidak perlu khawatir tentang arsitektur yang sedang dijalankan oleh program.sumber
long long
. Jadi semua tipe numerik akan menggunakan specifier tipe yang sama.NSLog("%@", @(1123));
NSLog("%li", (long)theNSInteger);
Anda harus menggunakan NSIntegers jika Anda perlu membandingkannya dengan nilai konstan seperti NSNotFound atau NSIntegerMax, karena nilai-nilai ini akan berbeda pada sistem 32-bit dan 64-bit, sehingga nilai indeks, jumlah dan sejenisnya: gunakan NSInteger atau NSUInteger.
Tidak ada salahnya menggunakan NSInteger di sebagian besar keadaan, kecuali bahwa itu memakan memori dua kali lebih banyak. Imbas memori sangat kecil, tetapi jika Anda memiliki sejumlah besar angka yang mengambang pada satu waktu, itu mungkin membuat perbedaan untuk menggunakan int.
Jika Anda DO menggunakan NSInteger atau NSUInteger, Anda akan ingin memasukkannya ke dalam bilangan bulat panjang atau bilangan bulat tak bertanda saat menggunakan string format, karena fitur Xcode baru mengembalikan peringatan jika Anda mencoba dan keluar NSInteger seolah-olah memiliki panjang yang diketahui. Anda juga harus berhati-hati saat mengirimnya ke variabel atau argumen yang diketik sebagai int, karena Anda mungkin kehilangan ketepatan dalam prosesnya.
Secara keseluruhan, jika Anda tidak berharap memiliki ratusan ribu memori sekaligus, lebih mudah menggunakan NSInteger daripada terus-menerus khawatir tentang perbedaan di antara keduanya.
sumber
Sampai saat ini (September 2014) saya akan merekomendasikan menggunakan
NSInteger/CGFloat
ketika berinteraksi dengan iOS API dll jika Anda juga membangun aplikasi Anda untuk arm64. Ini karena Anda kemungkinan akan mendapatkan hasil yang tidak terduga ketika Anda menggunakanfloat
,long
danint
mengetik.CONTOH: FLOAT / GANDA vs CGFLOAT
Sebagai contoh, kami menggunakan metode delegasi UITableView
tableView:heightForRowAtIndexPath:
.Dalam aplikasi 32-bit saja itu akan berfungsi dengan baik jika ditulis seperti ini:
float
adalah nilai 32-bit dan 44 yang Anda kembalikan adalah nilai 32-bit. Namun, jika kita mengkompilasi / menjalankan bagian kode yang sama dalam arsitektur arm64 64-bit, 44 akan menjadi nilai 64-bit. Mengembalikan nilai 64-bit ketika nilai 32-bit diharapkan akan memberikan tinggi baris yang tidak terduga.Anda dapat mengatasi masalah ini dengan menggunakan
CGFloat
tipeTipe ini mewakili 32-bit
float
dalam lingkungan 32-bit dan 64-bitdouble
dalam lingkungan 64-bit. Karenanya saat menggunakan tipe ini metode akan selalu menerima tipe yang diharapkan terlepas dari lingkungan kompilasi / runtime.Hal yang sama berlaku untuk metode yang mengharapkan bilangan bulat. Metode seperti itu akan mengharapkan nilai 32-bit
int
dalam lingkungan 32-bit dan 64-bitlong
dalam lingkungan 64-bit. Anda dapat menyelesaikan kasus ini dengan menggunakan tipeNSInteger
yang berfungsi sebagaiint
ataulong
berdasarkan pada kompilasi / runtime environmentemnt.sumber
Di iOS, saat ini tidak masalah jika Anda menggunakan
int
atauNSInteger
. Akan lebih penting jika / ketika iOS pindah ke 64-bit.Sederhananya,
NSInteger
s adalahint
dalam kode 32-bit (dan dengan demikian panjangnya 32-bit) danlong
s pada kode 64-bit (long
s dalam kode 64-bit lebar 64-bit, tetapi 32-bit dalam kode 32-bit). Alasan yang paling mungkin untuk menggunakanNSInteger
alih-alihlong
adalah untuk tidak merusak kode 32-bit yang ada (yang menggunakanint
s).CGFloat
memiliki masalah yang sama: pada 32-bit (setidaknya pada OS X), itufloat
; pada 64-bit, itudouble
.Pembaruan: Dengan diperkenalkannya iPhone 5s, iPad Air, iPad Mini dengan Retina, dan iOS 7, kini Anda dapat membuat kode 64-bit di iOS.
Pembaruan 2: Juga, menggunakan
NSInteger
s membantu dengan interoperabilitas kode Swift.sumber
int = 4 byte (ukuran tetap terlepas dari arsitek) NSInteger = tergantung pada ukuran arsitek (misalnya untuk arsitek 4 byte = 4 byte ukuran NSInteger)
sumber