2

[MyClass class]述語で必要なクラスのオブジェクトを見つけることができないのはなぜ[myObject class]ですか? 以下のコード例を参照してください。クラスの疑似インスタンスを利用可能にする必要なく、セット内のタイプ MyClass のオブジェクトを検索できるようにしたいと考えています。

MyClass* myObject = [[MyClass alloc] init];

これはうまくいきません...

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [MyClass class]];
NSArray* predicateResults = [mySet filteredSetUsingPredicate:predicate].allObjects;

これは機能します...

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [myObject class]];
NSArray* predicateResults = [mySet filteredSetUsingPredicate:predicate].allObjects;
4

2 に答える 2

14

のような述語

[NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [MyClass class]]

実際に動作します。(文書化された)とまったく同じ述語を返します

[NSComparisonPredicate
    predicateWithLeftExpression:[NSExpression expressionForEvaluatedObject]
                rightExpression:[NSExpression expressionForConstantValue:[MyClass class]]
                 customSelector:@selector(isMemberOfClass:)]

あなたの場合の問題は、クラスが等しいisMemberOfClass:かどうかを 比較する可能性があるため、これは のサブクラスのメンバーであるオブジェクトと一致しません。MyClass

これMyClassは、 がクラス クラスタでmyObjectあり、具体的なサブクラスのインスタンスである場合に発生する可能性があります。例えば:

NSString *myString = [[NSString alloc] initWithUTF8String:"hello world"];
Class c1 = [NSString class];   //  NSString
Class c2 = [myString class];   //  __NSCFString

BOOL b1 = [myString isMemberOfClass:c1]; // NO
BOOL b2 = [myString isMemberOfClass:c2]; // YES

その場合[myObject class]、 と[MyClass class]は異なります。これにより、一方の述語が機能し、もう一方の述語が機能しない理由が説明されます。

次のコードはisKindOfClass:代わりに使用し、期待される結果を生成します。

NSArray *array = @[@"123", @456, [NSArray array]];
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"self isKindOfClass: %@", [NSNumber class]];
NSArray* predicateResults = [array filteredArrayUsingPredicate:predicate];
NSLog(@"%@", predicateResults);
//  Output: ( 456 )
于 2013-08-22T11:11:38.697 に答える
4

質問に対する厳密な回答ではありませんが (MartinR の優れた回答を参照)、文書化された方法 (IMO) に代わるpredicateWithFormat:方法:

次のように、を使用predicateWithBlock:して を作成できます。NSPredicate

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

これはうまくいくはずです。

于 2013-08-22T10:31:53.620 に答える