Jika Anda tidak bisa mendapatkan objek dengan objectAtIndex: dari NSSet lalu bagaimana Anda mengambil objek?
objective-c
cocoa
cocoa-touch
object
nsset
node ninja
sumber
sumber
[[nsSetObjects allObjects] objectAtIndex: anyInteger]
Jawaban:
Ada beberapa kasus penggunaan untuk satu set. Anda dapat menghitung melalui (misalnya dengan
enumerateObjectsUsingBlock
atau NSFastEnumeration), panggilancontainsObject
untuk menguji keanggotaan, menggunakananyObject
untuk mendapatkan anggota (bukan acak), atau mengubahnya menjadi sebuah array (tanpa urutan tertentu) denganallObjects
.Satu set cocok jika Anda tidak menginginkan duplikat, tidak peduli dengan pesanan, dan menginginkan pengujian keanggotaan yang cepat.
sumber
member:
pesan ke set . Jika kembalinil
, himpunan tidak berisi objek yang sama dengan yang Anda berikan; jika mengembalikan penunjuk objek, maka penunjuk yang dikembalikan adalah ke objek yang sudah ada di set. Objek dalam himpunan harus diimplementasikanhash
danisEqual:
agar berguna.hash
perlu diterapkan; itu hanya akan berjalan lebih cepat jika Anda melakukannya.hash
di protokol NSObject: "Jika dua objek sama (sebagaimana ditentukan olehisEqual:
metode), mereka harus memiliki nilai hash yang sama." Saat ini, implementasi NSObjecthash
danisEqual:
menggunakan identitas objek (alamat). Jika Anda menimpaisEqual:
, Anda sedang menyiapkan kemungkinan objek yang tidak identik tetapi sama — yang, jika Anda tidak juga menimpanyahash
, akan tetap memiliki hash yang berbeda. Itu melanggar persyaratan bahwa objek yang sama memiliki hash yang sama.member:
, penampung hanya akan mencari di keranjang itu bucket (itulah sebabnya set jauh lebih cepat daripada array pada pengujian keanggotaan dan kamus jauh lebih cepat daripada array paralel pada pencarian nilai kunci). Jika objek yang dicari memiliki hash yang salah, maka container akan mencari di bucket yang salah, dan tidak menemukan yang cocok.-[NSObject hash]
adalah 0. Itu menjelaskan banyak hal. = SNSSet tidak memiliki metode objectAtIndex:
Coba panggil allObjects yang mengembalikan NSArray dari semua objek.
sumber
dimungkinkan untuk menggunakan filteredSetUsingPredicate jika Anda memiliki semacam pengenal unik untuk memilih objek yang Anda butuhkan.
Pertama buat predikat (dengan asumsi id unik Anda di objek disebut "pengenal" dan itu adalah NSString):
Dan kemudian pilih objek menggunakan predikat:
sumber
NSArray *myArray = [myNSSet allObjects];
ganti NSUInteger dengan indeks objek yang Anda inginkan.
sumber
Untuk Swift3 & iOS10:
sumber
NSSet menggunakan metode isEqual: (di mana objek yang Anda masukkan ke dalam set itu harus menimpa, sebagai tambahan, metode hash) untuk menentukan apakah ada objek di dalamnya.
Jadi, misalnya jika Anda memiliki model data yang mendefinisikan keunikannya dengan nilai id (katakanlah propertinya adalah:
maka Anda akan menerapkan isEqual: as
dan Anda dapat menerapkan hash:
Kemudian, Anda bisa mendapatkan sebuah objek dengan ID tersebut (serta memeriksa apakah itu ada di NSSet) dengan:
Tapi ya, satu-satunya cara untuk mendapatkan sesuatu dari NSSet adalah dengan mempertimbangkan apa yang mendefinisikan keunikannya sejak awal.
Saya belum menguji mana yang lebih cepat, tetapi saya menghindari penggunaan enumerasi karena itu mungkin linier sedangkan menggunakan metode member: akan jauh lebih cepat. Itulah salah satu alasan untuk lebih memilih penggunaan NSSet daripada NSArray.
sumber
sumber
Sebagian besar waktu Anda tidak peduli tentang mendapatkan satu objek tertentu dari satu set. Anda peduli tentang pengujian untuk melihat apakah satu set berisi objek. Itulah gunanya set. Saat Anda ingin melihat apakah sebuah objek berada dalam kumpulan kumpulan jauh lebih cepat daripada array.
Jika Anda tidak peduli dengan objek mana yang Anda dapatkan, gunakan
-anyObject
yang hanya memberi Anda satu objek dari set, seperti memasukkan tangan Anda ke dalam tas dan mengambil sesuatu.Jika Anda peduli tentang objek apa yang Anda dapatkan, gunakan
-member
yang mengembalikan objek tersebut, atau nihil jika tidak ada dalam set. Anda harus sudah memiliki objek tersebut sebelum memanggilnya.Berikut beberapa kode yang dapat Anda jalankan di Xcode untuk memahami lebih lanjut
sumber