Saya memiliki Film kelas, yang masing-masing menyimpan ID unik. Dalam C #, Java dll saya dapat mendefinisikan currentID int statis dan setiap kali saya mengatur ID saya dapat meningkatkan currentID dan perubahan terjadi pada tingkat kelas bukan tingkat objek. Bisakah ini dilakukan di Objective-C? Saya merasa sangat sulit untuk menemukan jawaban untuk ini.
Anda ingin ClassA Anda memiliki variabel kelas ClassB.
Anda menggunakan Objective-C sebagai bahasa pemrograman.
Objective-C tidak mendukung variabel kelas seperti halnya C ++.
Satu alternatif :
Mensimulasikan perilaku variabel kelas menggunakan fitur Objective-C
Deklarasikan / Definisikan variabel statis di dalam classA.m sehingga hanya dapat diakses untuk metode classA (dan semua yang Anda masukkan ke dalam classA.m).
Timpa metode inisialisasi kelas NSObject untuk menginisialisasi variabel statis sekali dengan instance dari ClassB.
Anda akan bertanya-tanya, mengapa saya harus menimpa metode inisialisasi NSObject. Dokumentasi Apple tentang metode ini memiliki jawaban: "runtime mengirimkan inisialisasi ke setiap kelas dalam suatu program tepat satu kali tepat sebelum kelas, atau kelas apa pun yang mewarisi darinya, dikirim pesan pertama dari dalam program. (Demikian metode ini mungkin tidak pernah dipanggil jika kelas tidak digunakan.) "
Jangan ragu untuk menggunakan variabel statis dalam metode class / instance ClassA.
Bisakah Anda memiliki variabel statis Tipe ClassA dalam classA.m?
goatlinks
6
ini mungkin pertanyaan konyol tapi bagaimana dengan pelepasan ingatan itu? tidak masalah karena itu harus hidup selama aplikasi berjalan?
samiq
1
@samiq, periksa Objective-C: Mengapa mempertahankan variabel statis? . Pointer ke objek tidak bisa dihapus, tetapi objek itu sendiri bisa. Anda mungkin tidak ingin melepaskannya karena kemungkinan besar Anda menginginkannya selama aplikasi berjalan, tetapi Anda akan menghemat memori jika Anda melepaskannya, jadi jika Anda tahu Anda tidak membutuhkannya lagi, maka Anda harus lepaskan.
ma11hew28
5
Jika inisialisasi () dijamin akan dipanggil hanya sekali, mengapa Anda memerlukan persyaratan "if (! ClassVariableName)"?
jb
23
@ Jamie, initializedipanggil sekali untuk setiap kelas (superclasses sebelum subclass), tetapi jika subclass tidak menimpa initialize, kelas induk initializeakan dipanggil lagi. Karenanya, seorang penjaga diperlukan jika Anda tidak ingin kode itu dieksekusi dua kali. Lihat Menginisialisasi Objek Kelas di Apple Objective-C docs.
big_m
31
Pada Xcode 8, Anda bisa mendefinisikan properti kelas di Obj-C. Ini telah ditambahkan untuk beroperasi dengan sifat statis Swift.
Objective-C sekarang mendukung properti kelas, yang beroperasi dengan properti tipe Swift. Mereka dinyatakan sebagai: @ properti (kelas) NSString * someStringProperty ;. Mereka tidak pernah disintesis. (23891898)
Berikut adalah posting penjelasan yang sangat menarik yang saya gunakan sebagai referensi untuk mengedit jawaban lama ini.
2011 Jawaban: (jangan gunakan ini, ini mengerikan)
Jika Anda benar-benar tidak ingin mendeklarasikan variabel global, ada opsi lain, mungkin tidak terlalu ortodoks :-), tetapi berfungsi ... Anda dapat mendeklarasikan metode "get & set" seperti ini, dengan variabel statis di dalam:
+(NSString*)testHolder:(NSString*)_test {staticNSString*test;if(_test != nil){if(test != nil)[test release];
test =[_test retain];}// if(test == nil)// test = @"Initialize the var here if you need to";return test;}
Jadi, jika Anda perlu mendapatkan nilainya, telepon saja:
NSString*testVal =[MyClass testHolder:nil]
Dan kemudian, ketika Anda ingin mengaturnya:
[MyClass testHolder:testVal]
Jika Anda ingin dapat mengatur pseudo-static-var ini menjadi nil, Anda dapat mendeklarasikan testHoldersebagai ini:
+(NSString*)testHolderSet:(BOOL)shouldSet newValue:(NSString*)_test {staticNSString*test;if(shouldSet){if(test != nil)[test release];
test =[_test retain];}return test;}
Keren, tetapi sebenarnya bukan variabel global karena tidak dapat diakses dari .mfile lain , dan saya pikir itu bagus untuk menjadi "global" di dalam Class.mfile.
ma11hew28
29
Pada file .m Anda, Anda dapat mendeklarasikan variabel sebagai statis:
staticClassName*variableName = nil;
Kemudian Anda dapat menginisialisasi pada +(void)initializemetode Anda .
Harap dicatat bahwa ini adalah variabel statis C biasa dan tidak statis dalam arti yang dipertimbangkan oleh Java atau C #, tetapi akan menghasilkan hasil yang serupa.
atau jika perlu diubah di waktu lain (misalnya dalam metode openConnection Anda), kemudian tambahkan di sana. Ingat itu bukan thread aman seperti ini, Anda harus melakukan sinkronisasi (atau lebih baik lagi, gunakan add atom) jika mungkin ada masalah threading.
Seperti kata pgb, tidak ada "variabel kelas," hanya "variabel instan." Cara objektif-c melakukan variabel kelas adalah variabel global statis di dalam file .m kelas. The "static" memastikan bahwa variabel tidak dapat digunakan di luar file itu (yaitu tidak dapat extern).
(Tegasnya bukan jawaban untuk pertanyaan, tetapi dalam pengalaman saya cenderung berguna ketika mencari variabel kelas)
Metode kelas sering dapat memainkan banyak peran yang akan dilakukan oleh variabel kelas dalam bahasa lain (mis. Konfigurasi yang berubah selama pengujian):
Sekarang, objek MyClspanggilan kelas Resource:changeSomething:dengan string @"Something general"pada panggilan ke doTheThing:, tetapi objek berasal dari MySpecialCasedengan string @"Something specific".
initialize
dipanggil sekali untuk setiap kelas (superclasses sebelum subclass), tetapi jika subclass tidak menimpainitialize
, kelas indukinitialize
akan dipanggil lagi. Karenanya, seorang penjaga diperlukan jika Anda tidak ingin kode itu dieksekusi dua kali. Lihat Menginisialisasi Objek Kelas di Apple Objective-C docs.Pada Xcode 8, Anda bisa mendefinisikan properti kelas di Obj-C. Ini telah ditambahkan untuk beroperasi dengan sifat statis Swift.
Berikut ini sebuah contoh
Maka Anda dapat mengaksesnya seperti ini:
Berikut adalah posting penjelasan yang sangat menarik yang saya gunakan sebagai referensi untuk mengedit jawaban lama ini.
2011 Jawaban: (jangan gunakan ini, ini mengerikan)
Jika Anda benar-benar tidak ingin mendeklarasikan variabel global, ada opsi lain, mungkin tidak terlalu ortodoks :-), tetapi berfungsi ... Anda dapat mendeklarasikan metode "get & set" seperti ini, dengan variabel statis di dalam:
Jadi, jika Anda perlu mendapatkan nilainya, telepon saja:
Dan kemudian, ketika Anda ingin mengaturnya:
Jika Anda ingin dapat mengatur pseudo-static-var ini menjadi nil, Anda dapat mendeklarasikan
testHolder
sebagai ini:Dan dua metode praktis:
Semoga ini bisa membantu! Semoga berhasil.
sumber
.m
file lain , dan saya pikir itu bagus untuk menjadi "global" di dalamClass.m
file.Pada file .m Anda, Anda dapat mendeklarasikan variabel sebagai statis:
Kemudian Anda dapat menginisialisasi pada
+(void)initialize
metode Anda .Harap dicatat bahwa ini adalah variabel statis C biasa dan tidak statis dalam arti yang dipertimbangkan oleh Java atau C #, tetapi akan menghasilkan hasil yang serupa.
sumber
Di file .m Anda, deklarasikan variabel global file:
kemudian dalam rutinitas init Anda, rujuk bahwa:
atau jika perlu diubah di waktu lain (misalnya dalam metode openConnection Anda), kemudian tambahkan di sana. Ingat itu bukan thread aman seperti ini, Anda harus melakukan sinkronisasi (atau lebih baik lagi, gunakan add atom) jika mungkin ada masalah threading.
sumber
Seperti kata pgb, tidak ada "variabel kelas," hanya "variabel instan." Cara objektif-c melakukan variabel kelas adalah variabel global statis di dalam file .m kelas. The "static" memastikan bahwa variabel tidak dapat digunakan di luar file itu (yaitu tidak dapat extern).
sumber
Ini akan menjadi pilihan:
Perhatikan bahwa metode ini akan menjadi satu-satunya metode untuk mengakses id, jadi Anda harus memperbaruinya dalam kode ini.
sumber
(Tegasnya bukan jawaban untuk pertanyaan, tetapi dalam pengalaman saya cenderung berguna ketika mencari variabel kelas)
Metode kelas sering dapat memainkan banyak peran yang akan dilakukan oleh variabel kelas dalam bahasa lain (mis. Konfigurasi yang berubah selama pengujian):
Sekarang, objek
MyCls
panggilan kelasResource:changeSomething:
dengan string@"Something general"
pada panggilan kedoTheThing:
, tetapi objek berasal dariMySpecialCase
dengan string@"Something specific"
.sumber
Anda dapat mengubah nama kelas sebagai classA.mm dan menambahkan fitur C ++ di dalamnya.
sumber
Kemungkinan lain adalah memiliki
NSNumber
subkelas singleton kecil.sumber