Objektif-C'deki her döngü için NSMutable sözlüğüne erişim


268

Objective-C'de değişebilir sözlük anahtarlarına ve değerlerine erişmekte zorluk yaşıyorum.

Varsayalım:

NSMutableDictionary *xyz=[[NSMutableDictionary alloc] init];

Anahtarları ve değerleri ayarlayabilirim. Şimdi, her bir tuşa ve değere erişmek istiyorum, ancak ayarlanan anahtar sayısını bilmiyorum.

PHP'de çok kolay, aşağıdaki gibi bir şey:

foreach ($xyz as $key => $value)

Objective-C'de nasıl mümkün olabilir?

Yanıtlar:


662
for (NSString* key in xyz) {
    id value = xyz[key];
    // do stuff
}

Bu, NSFastEnumeration protokolüne (10.5+ ve iOS'ta kullanılabilir) uyan her sınıf için geçerlidir, ancak NSDictionarydeğerler yerine anahtarları numaralandırmanıza izin veren birkaç koleksiyondan biridir. Onun hakkında senin önermek hızlı numaralandırma içinde Konu Programlama Koleksiyonu .

Oh, ancak eklemeliyim ki ASLA bir koleksiyonu üzerinde numaralandırırken modifiye etmemelisiniz .


4
Merak ediyordum, olmalıydı: için ([xyz allKeys] NSString * anahtar)) ?? Yoksa gerçekten önemli değil.
FlowUI. SimpleUITesting.com

6
@ user76859403 Bir sözlüğü numaralandırmak aslında anahtarları numaralandırır. for (NSString* key in [xyz allKeys])kavramsal olarak aynı şeydir.
zneak

Tuşları numaralandırırken sözlüğü değiştirmeniz gerekiyorsa [xyz allKeys] kullanın. Cevabımı aşağıda görebilirsiniz.
Brody Robertson

Bu döngü her zaman aynı sıraya dönüyor mu? Yoksa TableView bölümleri için kullanmak için başka bir yola mı ihtiyacımız var?
ymutlu

1
@ymutlu, Kakao sözlükleri sıralanmamış. Bu, yinelendikleri sırayı değiştirdiğinizde değişebileceği anlamına gelir.
zneak

98

Sadece blokları kullanarak değerleri ve anahtarları numaralandırmak için 10.6+ seçeneğini dışarıda bırakmamak için ...

[dict enumerateKeysAndObjectsUsingBlock:^(id key, id object, BOOL *stop) {
    NSLog(@"%@ = %@", key, object);
}];

İşlemlerin aynı anda gerçekleşmesini istiyorsanız:

[dict enumerateKeysAndObjectsWithOptions:NSEnumerationConcurrent
                              usingBlock:^(id key, id object, BOOL *stop) {
    NSLog(@"%@ = %@", key, object);
}];

2
Bir sözlükte numaralandırmanın 3 farklı yolu. . . heh, bu bana VB'nin 7 farklı türde döngüye sahip olduğu "En garip Dil Özelliği" cevabını hatırlatıyor.
dreamlax

3
Şey ... objectEnumerator 1994 yılında, for (... in ...) 2006 yılında eklendi ve Bloklar 2009 yılında eklendi. Numaralandırmanın blok şekli doğal serpinti.
bbum

Bu daha hızlı standardından daha görünüyor içinde ... için yapı: oneofthesedaysblog.com/block-vs-for-in-objective-c-enumeration
lkraider

1
@lkraider, aslında blok tabanlı numaralandırmayı yapı için for ... değil, eski bir for döngüsü ile karşılaştıran bu yazıya yorum yaptım.
Quinn Taylor

Ne *stopiçin? Bunu nasıl kullanıyorsunuz? Referans var mı?
borisdiakur

13

Numaralandırırken sözlüğü değiştirmeniz gerekiyorsa :

for (NSString* key in xyz.allKeys) {
    [xyz setValue:[NSNumber numberWithBool:YES] forKey:key];
}

Bunun nedeni, allKeysanahtarların bir kopyasını döndürmektir. Bu yüzden sözlüğü değiştirmek güvenlidir.
Honghao Zhang

5

Bir sözlüğü numaralandırmanın en kolay yolu

for (NSString *key in tDictionary.keyEnumerator) 
{
    //do something here;
}

nerede tDictionaryolduğunu NSDictionaryya da NSMutableDictionarysen yineleme istiyorum.



2

10.5 ve iPhone OS'de hızlı numaralandırma eklendi ve sadece sözdizimsel şeker değil, önemli ölçüde daha hızlı. Eski çalışma zamanını (yani 10.4 ve geri) hedeflemeniz gerekiyorsa, eski numaralandırma yöntemini kullanmanız gerekir:

NSDictionary *myDict = ... some keys and values ...
NSEnumerator *keyEnum = [myDict keyEnumerator];
id key;

while ((key = [keyEnum nextObject]))
{
    id value = [myDict objectForKey:key];
    ... do work with "value" ...
}

Sayıcı nesnesini serbest bırakmazsınız ve sıfırlayamazsınız. Baştan başlamak istiyorsanız, sözlükten yeni bir numaralandırıcı nesnesi istemeniz gerekir.


1

Sen kullanabilirsiniz -[NSDictionary allKeys]içinden tüm anahtarları ve döngü erişmek için.


2
Doğru, ancak bu, özellikle çok sayıda tuşa sahip sözlükler için oldukça israflı olabilen ekstra bir otomatik yayın dizisi oluşturur.
Quinn Taylor
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.