Pertanyaan saya adalah ini. Kapan seseorang menggunakan #import dan kapan seseorang menggunakan @class?
Jawaban sederhana: Anda #import
atau #include
ketika ada ketergantungan fisik. Jika tidak, Anda menggunakan deklarasi maju ( @class MONClass
, struct MONStruct
,@protocol MONProtocol
).
Berikut adalah beberapa contoh umum ketergantungan fisik:
- Nilai C atau C ++ (pointer atau referensi bukan ketergantungan fisik). Jika Anda memiliki
CGPoint
sebagai ivar atau properti, kompiler perlu melihat deklarasi CGPoint
.
- Superclass Anda.
- Metode yang Anda gunakan.
Terkadang jika saya menggunakan deklarasi @class, saya melihat peringatan kompiler umum seperti berikut: "peringatan: receiver 'FooController' adalah kelas maju dan @interface yang sesuai mungkin tidak ada."
Compiler sebenarnya sangat toleran dalam hal ini. Ini akan meninggalkan petunjuk (seperti yang di atas), tetapi Anda dapat dengan mudah membuang tumpukan Anda jika Anda mengabaikannya dan tidak melakukannya #import
dengan benar. Meskipun harus (IMO), kompiler tidak menjalankan ini. Di ARC, kompiler lebih ketat karena bertanggung jawab untuk penghitungan referensi. Apa yang terjadi adalah kompiler kembali ke default ketika menemukan metode yang tidak dikenal yang Anda panggil. Setiap nilai dan parameter pengembalian diasumsikan id
. Dengan demikian, Anda harus menghapus setiap peringatan dari basis kode Anda karena ini harus dianggap sebagai ketergantungan fisik. Ini analog dengan memanggil fungsi C yang tidak dideklarasikan. Dengan C, parameter diasumsikanint
.
Alasan Anda lebih suka deklarasi maju adalah bahwa Anda dapat mengurangi waktu pembuatan Anda dengan faktor karena ada ketergantungan minimal. Dengan deklarasi maju, kompiler melihat ada nama, dan dapat dengan benar mem-parsing dan mengkompilasi program tanpa melihat deklarasi kelas atau semua dependensinya ketika tidak ada ketergantungan fisik. Bangunan bersih membutuhkan waktu lebih sedikit. Bangunan tambahan membutuhkan waktu lebih sedikit. Tentu, Anda akan menghabiskan lebih banyak waktu untuk memastikan bahwa semua tajuk yang Anda butuhkan dapat dilihat oleh setiap terjemahan sebagai konsekuensinya, tetapi ini terbayar dengan waktu pembuatan yang berkurang dengan cepat (dengan asumsi proyek Anda tidak kecil).
Jika Anda menggunakan #import
atau #include
sebagai gantinya, Anda membuat lebih banyak pekerjaan di kompiler daripada yang diperlukan. Anda juga memperkenalkan dependensi tajuk yang rumit. Anda bisa menyamakan ini dengan algoritma brute-force. Kapan kamu#import
, Anda menyeret banyak informasi yang tidak perlu, yang membutuhkan banyak memori, disk I / O, dan CPU untuk mengurai dan mengkompilasi sumber.
ObjC cukup dekat dengan ideal untuk bahasa berbasis C berkaitan dengan ketergantungan karena NSObject
tipe tidak pernah bernilai -NSObject
jenis selalu referensi pointer dihitung. Jadi Anda bisa lolos dengan waktu kompilasi yang sangat cepat jika Anda menyusun dependensi program Anda dengan tepat dan meneruskan jika memungkinkan karena ada sangat sedikit ketergantungan fisik yang diperlukan. Anda juga dapat mendeklarasikan properti di ekstensi kelas untuk meminimalkan ketergantungan. Itu bonus besar untuk sistem besar - Anda akan tahu perbedaannya jika Anda pernah mengembangkan basis kode C ++ besar.
Oleh karena itu, rekomendasi saya adalah menggunakan ke depan jika memungkinkan, dan kemudian ke #import
mana ada ketergantungan fisik. Jika Anda melihat peringatan atau yang menyiratkan ketergantungan fisik - perbaiki semuanya. Cara mengatasinya #import
dalam file implementasi Anda.
Saat Anda membangun pustaka, Anda kemungkinan akan mengklasifikasikan beberapa antarmuka sebagai grup, dalam hal ini Anda akan #import
pustaka di mana ketergantungan fisik diperkenalkan (misalnya #import <AppKit/AppKit.h>
). Ini dapat memperkenalkan ketergantungan, tetapi pengelola perpustakaan sering kali dapat menangani dependensi fisik untuk Anda sesuai kebutuhan - jika mereka memperkenalkan fitur, mereka dapat meminimalkan dampak yang ditimbulkannya pada bangunan Anda.