Saya membuat klien Reddit untuk tujuan pembelajaran. Saya perlu memiliki file dengan konstanta di dalamnya. Saya berpikir tentang mengimpor file dalam Reddit-Prefix.pch
file untuk membuat konstanta tersedia untuk semua file. Apakah ini cara yang baik untuk melakukan sesuatu? Juga, saya telah melakukan penelitian dan menemukan beberapa metode untuk membuat konstanta, tetapi saya tidak tahu mana yang harus digunakan:
#define
makroconst
static const
extern const
enum
Jadi jalan mana yang lebih disukai? Apa konvensi itu? Saya tahu bahwa "itu tergantung" tetapi pertanyaan saya lebih spesifik adalah: Apa kasus penggunaan untuk masing-masing solusi?
Juga, jika menggunakan extern const
, apakah saya perlu mengimpor file, atau konstanta akan tersedia secara global tanpa mengimpor file?
Satu hal yang secara logis dapat saya simpulkan adalah hal itu enum
pilihan terbaik ketika mendefinisikan sesuatu seperti domain kesalahan khusus (apakah saya benar-benar benar?). Tapi bagaimana dengan yang lain?
sumber
enum
hanya berguna untuk nilai integral.#define
dan konstanta dapat berupa tipe data apa pun.const
,,static const
danextern const
semuanya sama kecuali untuk ruang lingkup. Jadi sebenarnya hanya ada tiga pilihan.Jawaban:
Pertanyaan pertama adalah ruang lingkup yang Anda inginkan dari konstanta Anda, yang sebenarnya adalah dua pertanyaan:
Jika mereka spesifik dan internal untuk satu kelas, menyatakan mereka sebagai
static const
di atas file .m, seperti:Jika mereka berkaitan dengan satu kelas tetapi harus publik / digunakan oleh kelas lain, nyatakan mereka sebagai
extern
di header dan mendefinisikannya di .m:Jika harus bersifat global, deklarasikan dalam tajuk dan tentukan dalam modul yang sesuai, khususnya untuk konstanta tersebut.
Anda dapat mencampur dan mencocokkan ini untuk konstanta yang berbeda dengan tingkat yang berbeda tentang bagaimana global yang Anda inginkan, dan untuk konstanta global yang berbeda yang tidak termasuk bersama — Anda dapat menempatkannya dalam modul terpisah, masing-masing dengan header sendiri, jika Anda ingin.
Kenapa tidak
#define
?Jawaban lama adalah "makro tidak memiliki informasi tipe", tetapi kompiler saat ini cukup pintar melakukan semua pengecekan tipe untuk literal (makro yang diperluas) serta variabel.
Jawaban modern adalah karena debugger tidak akan tahu tentang makro Anda. Anda tidak bisa mengatakan
[myThing addObserver:self forKey:MyThingNotificationKey]
dalam perintah debugger jikaMyThingNotificationKey
makro; debugger hanya bisa mengetahuinya jika itu adalah variabel.Kenapa tidak
enum
?Nah, rmaddy mengalahkan saya dalam komentar:
enum
hanya dapat mendefinisikan konstanta integer. Hal-hal seperti nomor pengenal serial, bit-mask, kode empat byte, dll.Untuk keperluan itu,
enum
sangat bagus dan Anda benar-benar harus menggunakannya. (Bahkan lebih baik, gunakan yangNS_ENUM
danNS_OPTIONS
macro .) Untuk hal-hal lain, Anda harus menggunakan sesuatu yang lain;enum
tidak melakukan apa pun kecuali bilangan bulat.Dan pertanyaan lainnya
Mungkin tidak berbahaya, tetapi mungkin berlebihan. Impor tajuk konstanta Anda di tempat yang Anda butuhkan.
#define
: Cukup terbatas. Sejujurnya saya tidak yakin ada alasan yang baik untuk menggunakan ini untuk konstanta.const
: Terbaik untuk konstanta lokal. Selain itu, Anda harus menggunakan ini untuk yang Anda deklarasikan di header dan sekarang mendefinisikan.static const
: Terbaik untuk konstanta khusus file (atau khusus kelas).extern const
: Anda harus menggunakan ini saat mengekspor konstanta di header.Anda perlu mengimpor file, baik di setiap file di mana Anda menggunakannya atau di header awalan.
sumber
static NSString *const
di.h
file sama sekali?static NSString *const foo = @"foo";
, maka tajuk menentukan apa string itu, dan itu harus sama di mana-mana - jika Anda pernah mengubah string dan berbagai pihak menggunakan versi header yang berbeda dengan string yang berbeda, maka string tidak akan cocok saat dijalankan waktu. Dalam suatu kerangka kerja, Anda ingin memberikan akses ke simbol saja, dan membiarkan kerangka kerja menjadi satu-satunya sumber nilai sebenarnya dari simbol itu, sehingga semua orang mendapatkan string yang sama dari satu tempat. Itu yangextern
membuatmu.#define
s: mereka tidak dijamin memiliki alamat yang sama dalam memori (tergantung pada bagaimana mereka dinyatakan, mereka dapat mengalokasikan contoh baru setiap kali mereka digunakan), jadi menggunakanmyObject == MyDefine
tidak akan selalu berfungsi seperti yang diharapkan, tapimyObject == MyStaticConst
akan.static NSString *const
bukannyastatic NSString const*
?? Ada perbedaan ?!static NSString const *
adalah sama denganstatic const NSString *
dan berarti "a (dapat diubah) pointer ke NSString konstan" - yang agak tidak berguna di sini karena NSString sudah tidak dapat diubah. Apa yang ingin Anda hanyastatic NSString * const
- yang merupakan "pointer konstan ke NSString"FOUNDATION_EXPORT
Pertimbangkan
FOUNDATION_EXPORT
untuk menggunakan kompatibilitas yang sedikit lebih banyak daripadaextern
yang didefinisikan dalam fondasi dan kompilasi ke format yang kompatibel untuk C, C ++, dan Win32.Seperti yang didefinisikan dalam NSObjCRuntime.h
sumber