Bagaimana saya bisa mendapatkan daftar (dalam bentuk NSArray
atau NSDictionary
) dari properti objek tertentu di Objective-C?
Bayangkan skenario berikut: Saya telah mendefinisikan kelas induk yang hanya diperluas NSObject
, yang menampung NSString
, a, BOOL
dan NSData
objek sebagai properti. Lalu saya memiliki beberapa kelas yang memperluas kelas induk ini, menambahkan banyak properti yang berbeda masing-masing.
Apakah ada cara saya bisa mengimplementasikan metode instance pada kelas induk yang melewati seluruh objek dan mengembalikan, katakanlah, NSArray
dari setiap properti kelas (anak) seperti NSStrings
yang tidak ada di kelas induk, jadi saya nanti bisa menggunakan ini NSString
untuk KVC?
[NSString stringWithCString:]
sudah usang demi[NSString stringWithCString:encoding:]
.Jawaban @ boliva bagus, tetapi perlu sedikit ekstra untuk menangani primitif, seperti int, long, float, double, dll.
Saya membangunnya untuk menambahkan fungsi ini.
sumber
#import <Foundation/Foundation.h>
di bagian atas file .h?Jawaban @ orange80 memiliki satu masalah: Ini sebenarnya tidak selalu mengakhiri string dengan 0s. Hal ini dapat menyebabkan hasil yang tidak terduga seperti crash saat mencoba mengubahnya menjadi UTF8 (Saya sebenarnya mengalami crashbug yang cukup mengganggu hanya karena itu. Sangat menyenangkan men-debug ^^). Saya memperbaikinya dengan benar-benar mendapatkan NSString dari atribut dan kemudian memanggil cStringUsingEncoding :. Ini bekerja seperti pesona sekarang. (Juga bekerja dengan ARC, setidaknya untuk saya)
Jadi ini versi kode saya sekarang:
sumber
Ketika saya mencoba dengan iOS 3.2, fungsi getPropertyType tidak bekerja dengan baik dengan deskripsi properti. Saya menemukan contoh dari dokumentasi iOS: "Objective-C Runtime Programming Guide: Declared Properties".
Berikut adalah kode yang direvisi untuk listing properti di iOS 3.2:
sumber
Saya telah menemukan bahwa solusi boliva berfungsi dengan baik di simulator, tetapi pada perangkat, substring dengan panjang tetap menyebabkan masalah. Saya telah menulis solusi yang lebih ramah Objective-C untuk masalah ini yang berfungsi pada perangkat. Dalam versi saya, saya mengonversi C-String dari atribut ke NSString dan melakukan operasi string di atasnya untuk mendapatkan substring dari deskripsi tipe saja.
sumber
Implementasi ini bekerja dengan tipe objek Objective-C dan primitif C. Ini kompatibel dengan iOS 8. Kelas ini menyediakan tiga metode kelas:
Mengembalikan kamus dari semua properti objek yang terlihat, termasuk yang dari semua kelas supernya.
Mengembalikan kamus dari semua properti kelas yang terlihat, termasuk yang dari semua kelas supernya.
Mengembalikan kamus dari semua properti yang terlihat yang spesifik untuk subkelas. Properti untuk superclass-nya adalah tidak disertakan.
Salah satu contoh yang berguna dari penggunaan metode ini adalah dengan menyalin objek ke instance subclass di Objective-C tanpa harus menentukan properti dalam metode salin . Sebagian dari jawaban ini didasarkan pada jawaban lain untuk pertanyaan ini, tetapi memberikan antarmuka yang lebih bersih ke fungsionalitas yang diinginkan.
Header:
Penerapan:
sumber
Jika seseorang juga perlu mendapatkan properti yang diwarisi dari kelas induk (seperti yang saya lakukan) berikut ini beberapa modifikasi pada kode " orange80 " untuk membuatnya rekursif:
sumber
Kata "atribut" agak kabur. Apakah yang Anda maksud adalah variabel instan, properti, metode yang terlihat seperti pengakses?
Jawaban dari ketiganya adalah "ya, tapi itu tidak mudah." The Objective-C runtime API termasuk fungsi untuk mendapatkan daftar Ivar, daftar metode atau daftar properti untuk kelas (misalnya,
class_copyPropertyList()
), dan kemudian sesuai fungsi untuk setiap jenis untuk mendapatkan nama item dalam daftar (misalnya,property_getName()
).Secara keseluruhan, ini bisa menjadi pekerjaan yang berat untuk memperbaikinya, atau setidaknya lebih banyak dari yang kebanyakan orang ingin lakukan untuk apa yang biasanya merupakan fitur yang sangat sepele.
Alternatifnya, Anda bisa menulis skrip Ruby / Python yang hanya membaca file header dan mencari apa pun yang Anda anggap "atribut" untuk kelas.
sumber
Saya bisa mendapatkan jawaban @ orange80 untuk bekerja DENGAN ARC DIAKTIFKAN … ... untuk apa yang saya inginkan - setidaknya ... tetapi bukan tanpa sedikit trial and error. Semoga informasi tambahan ini dapat menghindarkan seseorang dari kesedihan.
Simpan kelas-kelas yang dia gambarkan dalam jawabannya = sebagai kelas, dan dalam Anda
AppDelegate.h
(atau apa pun), put#import PropertyUtil.h
. Kemudian di ...metode (atau apapun)
…
Rahasianya adalah untuk memasukkan variabel instan kelas Anda ( dalam hal ini kelas saya
Gist
, dan contoh sayaGist
adalahgist
) yang ingin Anda tanyakan ... ke NSObject ...(id)
, dll, tidak akan memotongnya .. untuk berbagai, aneh , alasan esoteris. Ini akan memberi Anda beberapa keluaran seperti ...Untuk semua Apple yang tidak tahu malu / OCD yang membual tentang introspeksi "amazeballs" "ObjC ... Mereka pasti tidak membuatnya sangat mudah untuk melakukan" tampilan "sederhana" pada diri sendiri "," boleh dikatakan "..
Jika Anda benar-benar ingin menjadi sangat liar .. periksa .. class-dump , yang merupakan cara yang sangat gila untuk mengintip header kelas dari SETIAP yang dapat dieksekusi, dll ... Ini memberikan tampilan VERBOSE ke kelas Anda ... bahwa saya, secara pribadi, menemukan yang benar-benar membantu - dalam banyak, banyak keadaan. itu sebenarnya mengapa saya mulai mencari solusi untuk pertanyaan OP. berikut adalah beberapa parameter penggunaan .. selamat menikmati!
sumber
Anda memiliki tiga mantra ajaib
Sepotong kode berikut dapat membantu Anda.
sumber
Saya menggunakan fungsi boliva yang disediakan, tetapi ternyata itu berhenti bekerja dengan iOS 7. Jadi sekarang alih-alih static const char * getPropertyType (properti objc_property_t) seseorang dapat menggunakan yang berikut ini:
sumber
Untuk penonton Swift, Anda bisa mendapatkan fungsionalitas ini dengan memanfaatkan
Encodable
fungsionalitas tersebut. Saya akan menjelaskan caranya:Sesuaikan objek Anda dengan
Encodable
protokolBuat ekstensi untuk
Encodable
menyediakantoDictionary
fungsionalitasPanggil
toDictionary
instance objek Anda dan akseskeys
properti.Voila! Akses properti Anda seperti ini:
sumber
Jawaban-jawaban ini sangat membantu, tetapi saya membutuhkan lebih dari itu. Yang ingin saya lakukan adalah memeriksa apakah tipe kelas suatu properti sama dengan objek yang ada. Semua kode di atas tidak mampu melakukannya, karena: Untuk mendapatkan nama kelas dari sebuah objek, object_getClassName () mengembalikan teks seperti ini:
Tetapi jika memanggil getPropertyType (...) dari kode contoh di atas, dengan 4 struct_property_t objc dari properti kelas yang didefinisikan seperti ini:
itu mengembalikan string masing-masing sebagai berikut:
Jadi tidak dapat menentukan apakah NSObject mampu menjadi nilai salah satu properti kelas. Lalu bagaimana cara melakukannya?
Berikut ini contoh kode lengkap saya (fungsi getPropertyType (...) sama seperti di atas):
sumber