Saya baru mengenal pemrograman Mac / iPhone dan Objective-C. Di C # dan Java kita memiliki "generik", kelas koleksi yang anggotanya hanya dari tipe yang dideklarasikan. Misalnya, dalam C #
Dictionary<int, MyCustomObject>
hanya dapat berisi kunci yang bilangan bulat dan nilai yang bertipe MyCustomObject. Apakah mekanisme serupa ada di Objective-C?
Jawaban:
Di Xcode 7, Apple telah memperkenalkan 'Generasi Ringan' ke Objective-C. Di Objective-C, mereka akan menghasilkan peringatan kompiler jika ada ketidakcocokan tipe.
Dan dalam kode Swift, mereka akan menghasilkan kesalahan kompiler:
Lightweight Generics dimaksudkan untuk digunakan dengan NSArray, NSDictionary dan NSSet, tetapi Anda juga dapat menambahkannya ke kelas Anda sendiri:
Objective-C akan berperilaku seperti sebelumnya dengan peringatan kompiler.
tetapi Swift akan mengabaikan informasi Generic sepenuhnya. (Tidak lagi benar dalam Swift 3+.)
Berinteraksi dengan API Objective-C
sumber
MyClass <Foo: id<Bar>>
, kode Swift Anda akan menganggap nilai adalah jenis kendala Anda, yang memberi Anda sesuatu untuk dikerjakan. Namun, subclass khusus dariMyClass
jenis khusus mereka akan diabaikan (terlihat efektif sama dengan generikMyClass
). Lihat github.com/bgerstle/LightweightGenericsExampleTidak, tidak ada obat generik di Objective-C kecuali Anda ingin menggunakan template C ++ di kelas koleksi kustom Anda sendiri (yang saya sangat tidak menyarankan).
Objective-C memiliki pengetikan dinamis sebagai fitur, yang berarti bahwa runtime tidak peduli dengan jenis objek karena semua objek dapat menerima pesan. Saat Anda menambahkan objek ke koleksi bawaan, mereka hanya diperlakukan seolah-olah mereka diketik
id
. Tapi jangan khawatir, cukup kirim pesan ke objek-objek seperti biasa; itu akan berfungsi dengan baik (kecuali tentu saja satu atau lebih objek dalam koleksi tidak menanggapi pesan yang Anda kirim) .Generik diperlukan dalam bahasa seperti Java dan C # karena mereka kuat, bahasa yang diketik secara statis. Ballgame yang benar-benar berbeda dari fitur pengetikan dinamis Objective-C.
sumber
Tidak, tetapi untuk membuatnya lebih jelas Anda dapat berkomentar dengan jenis objek yang ingin Anda simpan, saya telah melihat ini dilakukan beberapa kali ketika Anda perlu menulis sesuatu di Jawa 1.4 saat ini) misalnya:
atau
sumber
Tidak ada obat generik di Objective-C.
Dari Documents
sumber
Apple telah menambahkan obat generik ke ObjC di XCode 7:
lihat di sini: https://developer.apple.com/library/prerelease/mac/documentation/Swift/Conceptual/BuildingCocoaApps/WorkingWithCocoaDataTypes.html#//apple_ref/doc/uid/TP40014216-CH6-ID61
sumber
Ini dirilis dalam Xcode 7 (akhirnya!)
Perhatikan bahwa dalam kode Objective C, itu hanya pemeriksaan waktu kompilasi; tidak akan ada kesalahan run-time hanya untuk menempatkan jenis yang salah ke koleksi atau menugaskan ke properti yang diketik.
Menyatakan:
Menggunakan:
Hati-hati dengan
*
itu.sumber
NSArr generik dapat direalisasikan dengan mensubclassing
NSArray
, dan mendefinisikan ulang semua metode yang disediakan dengan yang lebih membatasi. Sebagai contoh,harus didefinisikan ulang di
sebagai
untuk NSArray hanya mengandung NSStrings.
Subkelas yang dibuat dapat digunakan sebagai pengganti drop-in dan membawa banyak fitur yang berguna: peringatan kompiler, akses properti, pembuatan kode yang lebih baik dan penyelesaian-di Xcode. Semua ini adalah fitur waktu kompilasi, tidak perlu mendefinisikan ulang implementasi yang sebenarnya - metode NSArray masih dapat digunakan.
Mungkin untuk mengotomatisasi ini dan membuatnya menjadi hanya dua pernyataan, yang membuatnya dekat dengan bahasa yang mendukung obat generik. Saya telah membuat otomatisasi dengan WMGenericCollection , di mana templat disediakan sebagai C Preprocessor Macros.
Setelah mengimpor file header yang berisi makro, Anda bisa membuat NSArray umum dengan dua pernyataan: satu untuk antarmuka dan satu untuk implementasi. Anda hanya perlu memberikan tipe data yang ingin Anda simpan dan nama untuk subclass Anda. WMGenericCollection menyediakan template untuk
NSArray
,NSDictionary
danNSSet
, serta rekanan yang bisa berubah.Contoh:
List<int>
dapat direalisasikan oleh kelas kustom yang disebutNumberArray
, yang dibuat dengan pernyataan berikut:Setelah dibuat
NumberArray
, Anda dapat menggunakannya di mana saja di proyek Anda. Itu tidak memiliki sintaks<int>
, tetapi Anda dapat memilih skema penamaan Anda sendiri untuk label ini sebagai kelas sebagai templat.sumber
Melihat:
https://github.com/tomersh/Objective-C-Generics
Tampaknya menjadi semacam generik orang miskin, dengan menggunakan kembali mekanisme pemeriksaan protokol.
sumber
Sekarang mimpi menjadi kenyataan - ada Generik di Objective-C sejak hari ini (terima kasih, WWDC). Ini bukan lelucon - di halaman resmi Swift:
Dan gambar yang membuktikan ini:
sumber
Hanya ingin melompat ke sini. Saya sudah menulis posting blog di sini tentang Generics.
Hal yang ingin saya sumbangkan adalah Generik dapat ditambahkan ke kelas mana pun , bukan hanya kelas koleksi seperti yang ditunjukkan Apple.
Saya telah berhasil menambahkan kemudian ke berbagai kelas karena mereka bekerja persis sama dengan koleksi Apple. yaitu. kompilasi pemeriksaan waktu, penyelesaian kode, memungkinkan penghapusan gips, dll.
Nikmati.
sumber
Kelas-kelas Koleksi yang disediakan oleh kerangka kerja Apple dan GNUStep bersifat semi-generik karena mereka menganggap bahwa mereka diberikan objek, beberapa yang dapat diurutkan dan beberapa yang merespons pesan tertentu. Untuk primitif seperti float, ints, dll, semua struktur array C utuh dan dapat digunakan, dan ada objek pembungkus khusus untuk digunakan dalam kelas koleksi umum (mis. NSNumber). Selain itu, kelas Koleksi mungkin sub-kelas (atau secara khusus dimodifikasi melalui kategori) untuk menerima objek dari jenis apa pun, tetapi Anda harus menulis sendiri semua kode penanganan jenis. Pesan dapat dikirim ke objek apa pun tetapi harus mengembalikan nol jika tidak sesuai untuk objek tersebut, atau pesan tersebut harus diteruskan ke objek yang sesuai. Kesalahan tipe sebenarnya harus ditangkap pada waktu kompilasi, bukan pada saat dijalankan. Pada saat run-time mereka harus ditangani atau diabaikan. Akhirnya, Objc menyediakan fasilitas refleksi run-time untuk menangani kasus rumit dan respons pesan, tipe spesifik, dan layanan dapat diperiksa pada suatu objek sebelum dikirim pesan atau dimasukkan ke dalam koleksi yang tidak pantas. Berhati-hatilah bahwa pustaka dan kerangka kerja yang berbeda mengadopsi konvensi yang berbeda tentang bagaimana objek mereka berperilaku ketika mengirim pesan yang tidak memiliki respons kode, jadi RTFM. Selain program mainan dan build debugging, sebagian besar program tidak harus crash kecuali mereka benar-benar mengacau dan mencoba untuk menulis data buruk ke memori atau disk, melakukan operasi ilegal (mis. Bagi dengan nol, tetapi Anda juga dapat menangkapnya), atau mengaksesnya sumber daya sistem terlarang. Dinamisme dan run-time dari Objective-C memungkinkan hal-hal gagal dengan anggun dan harus dibangun ke dalam kode Anda. (PETUNJUK) jika Anda mengalami masalah dengan kemurahan hati dalam fungsi Anda, coba beberapa spesifisitas. Tulis fungsi-fungsi dengan tipe-tipe tertentu dan biarkan runtime memilih (itulah sebabnya mereka disebut penyeleksi!) Fungsi-anggota yang sesuai pada saat run-time.
sumber