Saya menguji beberapa isa swizzling dengan Swift, dan menemukan bahwa itu hanya berfungsi ketika NSObject adalah kelas super (langsung atau lebih jauh), atau dengan menggunakan dekorasi '@objc'. Jika tidak, itu akan mengikuti gaya statis- dan vtable-dispatch, seperti C ++.
Apakah normal untuk menentukan kelas Swift tanpa kelas dasar Cocoa / NSObject? Jika saya khawatir, ini berarti mengabaikan banyak dinamisme Objective-C, seperti intersepsi metode dan introspeksi run-time.
Perilaku waktu proses dinamis berada di jantung fitur seperti pengamat properti, Data Inti, Pemrograman Berorientasi Aspek , Perpesanan Pesanan Tinggi , kerangka kerja analitis & logging, dan sebagainya.
Menggunakan gaya pemanggilan metode Objective-C menambahkan sekitar 20 operan kode mesin ke pemanggilan metode, jadi dalam situasi tertentu ( banyak panggilan ketat ke metode dengan badan kecil ) pengiriman statis dan vtable gaya C ++ dapat bekerja lebih baik.
Tetapi mengingat aturan umum 95-5 ( 95% peningkatan kinerja berasal dari penyetelan 5% kode ), bukankah masuk akal untuk memulai dengan fitur dinamis yang kuat dan mengeras jika diperlukan?
sumber
Jawaban:
Kelas Swift yang merupakan subkelas dari NSObject:
objc_msgSend()
untuk panggilan ke (sebagian besar) metode merekaKelas Swift yang bukan merupakan subkelas dari NSObject:
objc_msgSend()
untuk panggilan ke metode mereka (secara default)Subclassing NSObject di Swift memberi Anda fleksibilitas runtime Objective-C tetapi juga kinerja Objective-C. Menghindari NSObject dapat meningkatkan kinerja jika Anda tidak membutuhkan fleksibilitas Objective-C.
Edit:
Dengan Xcode 6 beta 6, atribut dinamis muncul. Ini memungkinkan kita untuk menginstruksikan Swift bahwa suatu metode harus menggunakan pengiriman dinamis, dan oleh karena itu akan mendukung intersepsi.
sumber
Saya juga menemukan bahwa jika mendasarkan kelas Swift pada NSObject, saya melihat beberapa perilaku run-time yang tidak terduga yang dapat menyembunyikan bug pengkodean. Berikut ini contohnya.
Dalam contoh ini, di mana kita tidak mendasarkan pada NSObject, kompilator dengan benar menemukan kesalahan dalam testIncorrect_CompilerShouldSpot, melaporkan "... 'MyClass' tidak dapat diubah menjadi 'MirrorDisposition'"
Dalam contoh ini, di mana kami mendasarkan pada NSObject , compiler tidak melihat kesalahan dalam testIncorrect_CompilerShouldSpot:
Saya kira moralnya adalah, hanya berdasarkan NSObject di mana Anda benar-benar harus!
sumber
Menurut referensi bahasa, tidak ada persyaratan untuk kelas untuk membuat subkelas kelas akar standar apa pun, sehingga Anda dapat menyertakan atau menghilangkan kelas super sesuai kebutuhan.
Perhatikan bahwa menghilangkan superclass dari deklarasi kelas, tidak menetapkan superclass dasar implisit dalam bentuk apa pun. Ini mendefinisikan kelas dasar, yang secara efektif akan menjadi akar untuk hierarki kelas independen.
Dari referensi bahasa:
Mencoba mereferensikan
super
dari kelas tanpa kelas super (yaitu kelas dasar) akan menghasilkan kesalahan waktu kompilasisumber
Saya yakin bahwa sebagian besar data Swift tidak akan tersedia
objc
. Hanya bagian-bagian yang perlu berkomunikasi dengan infrastruktur Objective C yang akan secara eksplisit ditandai.Sejauh mana introspeksi runtime akan ditambahkan ke bahasa, saya tidak tahu. Intersepsi metode kemungkinan akan menjadi hanya mungkin jika metode secara eksplisit mengizinkannya. Ini adalah tebakan saya, tetapi hanya desainer bahasa di dalam Apple yang benar-benar tahu kemana tujuan mereka sebenarnya.
sumber
educated guesses
dalam beberapa tahun dari sekarang. Tapi untuk saat ini itu hanya tanda tanya besar.Kalimat berikut ini disalin dari Swift-eBook Apple dan memberikan jawaban yang sesuai untuk pertanyaan Anda:
Mendefinisikan Kelas-Basis
Setiap kelas yang tidak mewarisi dari kelas lain dikenal sebagai kelas dasar.
Kelas Swift tidak mewarisi dari kelas dasar universal. Kelas yang Anda tentukan tanpa menentukan superclass otomatis menjadi kelas dasar untuk Anda bangun.
Referensi
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Inheritance.html#//apple_ref/doc/uid/TP40014097-CH17-XID_251sumber
Itu normal. Lihatlah tujuan desain Swift: Tujuannya adalah untuk menghilangkan kelas besar masalah pemrograman. Metode swizzling mungkin bukan salah satu hal yang ingin Anda lakukan dengan Swift.
sumber