Saya baru saja memulai pemrograman Objective-C dan, memiliki latar belakang di Jawa, bertanya-tanya bagaimana orang menulis program Objective-C berurusan dengan metode pribadi.
Saya mengerti mungkin ada beberapa konvensi dan kebiasaan dan berpikir tentang pertanyaan ini sebagai agregator teknik terbaik yang digunakan orang berurusan dengan metode pribadi di Objective-C.
Harap sertakan argumen untuk pendekatan Anda saat mempostingnya. Mengapa ini bagus? Kekurangan apa yang dimilikinya (yang Anda ketahui) dan bagaimana Anda menghadapinya?
Adapun temuan saya sejauh ini.
Dimungkinkan untuk menggunakan kategori [mis. MyClass (Private)] yang didefinisikan dalam file MyClass.m untuk mengelompokkan metode pribadi.
Pendekatan ini memiliki 2 masalah:
- Xcode (dan kompiler?) Tidak memeriksa apakah Anda mendefinisikan semua metode dalam kategori pribadi di blok @ implementasi yang sesuai
- Anda harus meletakkan @interface mendeklarasikan kategori pribadi Anda di awal file MyClass.m, jika tidak Xcode mengeluh dengan pesan seperti "self mungkin tidak menanggapi pesan" privateFoo ".
Masalah pertama dapat diselesaikan dengan kategori kosong [mis. MyClass ()].
Yang kedua sangat mengganggu saya. Saya ingin melihat metode pribadi diimplementasikan (dan didefinisikan) di dekat akhir file; Saya tidak tahu apakah itu mungkin.
sumber
Jawaban:
Tidak ada, seperti yang orang lain katakan, hal seperti metode pribadi di Objective-C. Namun, mulai dari Objective-C 2.0 (artinya Mac OS X Leopard, iPhone OS 2.0, dan yang lebih baru) Anda dapat membuat kategori dengan nama kosong (yaitu
@interface MyClass ()
) yang disebut Ekstensi Kelas . Apa yang unik tentang ekstensi kelas adalah bahwa implementasi metode harus sama@implementation MyClass
dengan metode publik. Jadi saya menyusun kelas saya seperti ini:Dalam file .h:
Dan dalam file .m:
Saya pikir keuntungan terbesar dari pendekatan ini adalah memungkinkan Anda untuk mengelompokkan implementasi metode Anda berdasarkan fungsi, bukan oleh perbedaan publik / pribadi (terkadang arbitrer).
sumber
if (bSizeDifference && [self isSizeDifferenceSignificant:fWidthCombined])...
Kemudian fWidthCombined selalu datang sebagai 0.Sebenarnya tidak ada "metode pribadi" di Objective-C, jika runtime dapat menentukan implementasi yang akan digunakan. Tapi itu bukan untuk mengatakan bahwa tidak ada metode yang bukan bagian dari antarmuka yang didokumentasikan. Untuk metode-metode itu, saya pikir suatu kategori baik-baik saja. Daripada meletakkan
@interface
di bagian atas file .m seperti poin 2 Anda, saya akan memasukkannya ke file .h sendiri. Sebuah konvensi yang saya ikuti (dan telah saya lihat di tempat lain, saya pikir ini adalah konvensi Apple karena Xcode sekarang memberikan dukungan otomatis untuknya) adalah memberi nama file seperti itu setelah kelas dan kategorinya dengan tanda + yang memisahkannya, sehingga@interface GLObject (PrivateMethods)
dapat ditemukan diGLObject+PrivateMethods.h
. Alasan untuk menyediakan file header adalah agar Anda dapat mengimpornya di kelas uji unit Anda :-).By the way, sejauh menerapkan / mendefinisikan metode di dekat akhir file .m yang bersangkutan, Anda dapat melakukannya dengan kategori dengan menerapkan kategori di bagian bawah file .m:
atau dengan ekstensi kelas (hal yang Anda sebut "kategori kosong"), cukup tentukan metode tersebut sebagai yang terakhir. Metode Objective-C dapat didefinisikan dan digunakan dalam urutan apa pun dalam implementasi, jadi tidak ada yang menghentikan Anda menempatkan metode "pribadi" di akhir file.
Bahkan dengan ekstensi kelas saya akan sering membuat header terpisah (
GLObject+Extension.h
) sehingga saya dapat menggunakan metode tersebut jika diperlukan, meniru visibilitas "teman" atau "dilindungi".Karena jawaban ini awalnya ditulis, compiler dentang telah mulai melakukan dua lintasan untuk metode Objective-C. Ini berarti Anda dapat menghindari mendeklarasikan metode "pribadi" Anda sepenuhnya, dan apakah itu di atas atau di bawah situs panggilan, mereka akan ditemukan oleh kompiler.
sumber
Walaupun saya bukan ahli Objective-C, saya pribadi hanya mendefinisikan metode dalam implementasi kelas saya. Memang, itu harus didefinisikan sebelum (di atas) metode apa pun yang memanggilnya, tetapi pasti membutuhkan sedikit pekerjaan untuk dilakukan.
sumber
Menentukan metode pribadi Anda di
@implementation
blok sangat ideal untuk sebagian besar tujuan. Dentang akan melihat ini di dalam@implementation
, terlepas dari perintah deklarasi. Tidak perlu mendeklarasikan mereka dalam kelanjutan kelas (alias ekstensi kelas) atau kategori bernama.Dalam beberapa kasus, Anda perlu mendeklarasikan metode dalam kelanjutan kelas (misalnya jika menggunakan pemilih antara kelanjutan kelas dan
@implementation
).static
fungsi sangat baik untuk metode pribadi yang sangat sensitif atau kecepatan kritis.Suatu konvensi untuk penamaan awalan dapat membantu Anda menghindari override metode pribadi (saya menemukan nama kelas sebagai awalan aman).
Kategori yang diberi nama (mis.
@interface MONObject (PrivateStuff)
) Bukan ide yang sangat baik karena potensi tabrakan penamaan saat memuat. Mereka benar-benar hanya berguna untuk teman atau metode yang dilindungi (yang jarang merupakan pilihan yang baik). Untuk memastikan Anda diperingatkan tentang implementasi kategori yang tidak lengkap, Anda harus benar-benar mengimplementasikannya:Inilah sedikit cheat sheet beranotasi:
MONObject.h
MONObject.m
Pendekatan lain yang mungkin tidak jelas: tipe C ++ bisa sangat cepat dan memberikan tingkat kontrol yang jauh lebih tinggi, sambil meminimalkan jumlah metode objek yang diekspor dan dimuat.
sumber
Anda bisa mencoba mendefinisikan fungsi statis di bawah atau di atas implementasi Anda yang membawa pointer ke instance Anda. Ini akan dapat mengakses variabel instance Anda.
sumber
Anda bisa menggunakan blok?
Saya sadar ini adalah pertanyaan lama, tetapi ini adalah salah satu pertanyaan pertama yang saya temukan ketika saya mencari jawaban untuk pertanyaan ini. Saya belum melihat solusi ini dibahas di tempat lain, jadi beri tahu saya jika ada sesuatu yang bodoh dalam melakukan ini.
sumber
static
). Tapi saya telah bereksperimen dengan menetapkan blok ke guci pribadi (dari metode init) - agak gaya JavaScript - yang juga memungkinkan akses ke guci pribadi, sesuatu yang tidak mungkin dari fungsi statis. Belum yakin mana yang saya sukai.setiap objek di Objective C sesuai dengan protokol NSObject, yang menampung metode performSelector : . Saya sebelumnya juga mencari cara untuk membuat beberapa metode "pembantu atau pribadi" yang saya tidak perlu diekspos di tingkat publik. Jika Anda ingin membuat metode pribadi tanpa overhead dan tidak harus mendefinisikannya di file header Anda, maka coba ini ...
tentukan metode Anda dengan tanda tangan yang mirip dengan kode di bawah ini ...
maka ketika Anda perlu referensi metode sebut saja sebagai pemilih ...
baris kode ini akan memanggil metode yang Anda buat dan tidak memiliki peringatan yang mengganggu tentang tidak mendefinisikannya dalam file header.
sumber
Jika Anda ingin menghindari
@interface
blok di atas, Anda selalu dapat menempatkan deklarasi pribadi di file lainMyClassPrivate.h
tidak ideal tetapi tidak mengacaukan implementasi.MyClass.h
MyClassPrivate.h
MyClass.m
sumber
Satu hal lagi yang belum saya lihat disebutkan di sini - Xcode mendukung file .h dengan "_private" pada namanya. Katakanlah Anda memiliki kelas MyClass - Anda memiliki MyClass.m dan MyClass.h dan sekarang Anda juga dapat memiliki MyClass_private.h. Xcode akan mengenali ini dan memasukkannya dalam daftar "Rekan" di Asisten Editor.
sumber
Tidak ada cara untuk mengatasi masalah # 2. Itulah cara kompiler C (dan karenanya kompiler Objective-C) bekerja. Jika Anda menggunakan editor XCode, fungsi popup akan membuatnya mudah untuk dinavigasi
@interface
dan@implementation
memblokir file.sumber
Ada manfaat dari tidak adanya metode pribadi. Anda bisa memindahkan logika yang ingin Anda sembunyikan ke kelas yang terpisah dan menggunakannya sebagai delegasi. Dalam hal ini Anda dapat menandai objek yang didelegasikan sebagai pribadi dan tidak akan terlihat dari luar. Memindahkan logika ke kelas yang terpisah (mungkin beberapa) membuat desain proyek Anda lebih baik. Karena kelas Anda menjadi lebih sederhana dan metode Anda dikelompokkan dalam kelas dengan nama yang tepat.
sumber
Seperti yang orang lain katakan, mendefinisikan metode pribadi dalam
@implementation
blok adalah OK untuk sebagian besar tujuan.Pada topik organisasi kode - Saya ingin mereka tetap bersama di bawah
pragma mark private
untuk navigasi yang lebih mudah di Xcodesumber