2010-03-31 16 views
23

Sınıf tipine göre filtrelemek için bir yüklem inşa etmenin bir yolu var mı?NSArray sınıfına filtre uygulamak mümkün mü?

Şu anda diziden geçiyorum ve her nesnenin sınıfını kontrol ediyorum. Belki daha temiz bir yol var mı?

+0

Neden bu gibi farklı nesneleri ilk sırada aynı diziye yerleştiriyorsunuz? –

+12

Bir sebep, bir dizi soyut sınıfınız varsa. Tüm Kişiler sınıflarına sahip olabilirsiniz, ancak Doktorları veya Avukatları filtrelemek istiyorsunuz. – rob5408

cevap

22

Öyle gibi bir "cf_className" yöntemi ekler NSObject bir kategori ekleyebilirsiniz: Üzerinde iseniz

NSPredicate * p = [NSPredicate predicateWithFormat:@"cf_className = %@", aClass]; 
NSArray * filtered = [anArray filteredArrayUsingPredicate:p]; 

: Eğer gibi yüklemleri kullanabilirsiniz Oradan

@interface NSObject (CFAdditions) 
- (NSString *) cf_className; 
@end 

@implementation NSObject (CFAdditions) 
- (NSString *) cf_className { 
    return NSStringFromClass([self class]); 
} 
@end 

Mac, kategoriyi oluşturmak yerine -[NSObject className]'u kullanabilirsiniz. IPhone'un bu yönteme sahip olmaması, dolayısıyla bir kategoriye olan ihtiyacı.

+8

Ayrıca self.class.description yazabilirsiniz –

+0

@BrianKing mükemmel puan –

70

Ayrıca sınıfta da sınıfları karşılaştırabilirsiniz.

Ancak, sınıf kümelerine ait nesneleri filtrelemeye çalışıyorsanız veya alt sınıflarınız varsa, muhtemelen beklediğiniz gibi çalışmaz. örneği Örneğin

, NSDateNSCFString aynı zamanda diğer spesifik özel sınıflarını olabilir, genellikle bir __NSCFDate ve NSString olup.

Büyük olasılıkla sette kendinizinkine geçmek ve test olarak -isKindOfClass: kullanmak daha iyidir.

Eğer gerçekten bunu yapabilirsin olsa NSPredicate kullanmak istediğiniz IF. Örnek olarak, bu, NSString'dan türetilen tüm nesneler için bir diziyi filtreler. Sıkı bir sınıf üyeliği istiyorsan isKindOfClass:'u isMemberOfClass: ile değiştirebilirsin.

Koleksiyondaki tüm nesnelerin uyguladığı herhangi bir seçici, bir argüman alır ve BOOL döndürse de çalışmalıdır.

NSArray *mixedArray = {...}; 
NSPredicate *predicate = [NSPredicate predicateWithFormat: 
             @"self isKindOfClass: %@", 
             [NSString class]]; 

NSLog(@"%@", [mixedArray filteredArrayUsingPredicate:predicate]); 
+1

+1 Seçiciyi doğrudan yüklemeye koymayı düşünmemiştim. Temiz! –

+1

Predicate Programlama Kılavuzu'nda (bu, bir dizilim dizesinde teknik olarak belgelenmemiş olarak ifade edilir) belirtilmez, ancak özel seçici özelliği şu referansla yedeklenir: http://developer.apple.com/mac/library/ dokümantasyon/Kakao/Referans/Temel/Sınıflar/NSComparisonPredicate_Class/Reference/NSComparisonPredicate.html # // apple_ref/occ/clm/NSComparisonPredicate/predicateWithLeftExpression: rightExpression: customSelector: Çok güzel. –

+0

Evet, aslında çok uzun bir yol yazmıştım ama bir çömlek üzerinde biçim dizgisinde denedim ve işe yaradığını gördüğüme şaşırdım. –

22

iOS 4 ve Mac OS 10.6 başlayarak, bir de +[NSPredicate predicateWithBlock:] kullanabilirsiniz. Örneğin:

NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary *bindings) { 
    return [object isKindOfClass:[NSString class]]; 
}]; 

Bu Objective-C yerine predicateWithFormat: gerektirdiği yüklem sözdiziminde tamamen sizin yüklemler ifade etmesini sağlar.

+4

bu bir daha fazla oy hak ediyor –

İlgili konular