2010-03-31 118 views
23

有沒有一種方法構造謂詞來按類類型過濾?是否可以按類過濾NSArray?

我目前循環訪問數組並檢查每個對象的類。也許有一個更清潔的方式?

+0

爲什麼你把這些不同的物體放在同一個數組中? – 2010-04-02 13:58:13

回答

22

你可以添加一個類別以NSObject中,增加了一個 「cf_className」 的方法,像這樣:

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

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

從那裏,你可以使用謂詞這樣的:如果你在

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

在Mac中,您只需使用-[NSObject className]而不必創建類別。 iPhone沒有這種方法,因此需要一個類別。

+8

你也可以做self.class.description – 2012-01-12 18:23:59

+0

@BrianKing優秀點 – 2012-01-12 18:55:33

70

您可以直接在謂詞中比較類。

但是,如果您嘗試過濾屬於類集羣的對象或者您有子類,它可能不會如您所期望的那樣工作。

例如,NSDate在實例化時通常是__NSCFDateNSString可以是NSCFString以及其他特定的私有類。

這可能是更好的只是循環通過設置,並使用-isKindOfClass:作爲測試。

IF真的想用NSPredicate但你可以做到這一點。作爲一個例子,這將過濾來自NSString的所有對象的數組。如果您想要嚴格的班級會員資格,您可以用isMemberOfClass:替換isKindOfClass:

集合中所有對象實現的任何選擇器都帶有一個參數並返回BOOL應該可以工作。

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

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

+1我從來沒有想過把選擇器直接放在謂詞中。整齊! – 2010-04-01 04:27:08

+1

「謂詞編程指南」中沒有提及它(這意味着在格式字符串中進行此操作在技術上沒有記錄),但自定義選擇器功能由參考進行備份:http://developer.apple.com/mac/library/ documentation/Cocoa/Reference/Foundation/Classes/NSComparisonPredicate_Class/Reference/NSComparisonPredicate.html#// apple_ref/occ/clm/NSComparisonPredicate/predicateWithLeftExpression:rightExpression:customSelector:Very cool。 – 2010-04-02 14:00:24

+0

是的,我原本寫了很長的一段路,但是百靈在格式化字符串中試了一下,很驚訝地看到它的工作。 – 2010-04-02 16:01:25

22

從iOS 4和Mac OS 10.6開始,也可以使用+[NSPredicate predicateWithBlock:]。例如:

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

這可以讓你純粹表達自己的謂詞在Objective-C,而不是由predicateWithFormat:所需的謂詞的語法。

+4

這一個值得更多的選票 – 2014-07-30 15:28:12