2011-09-06 13 views

答えて

23

あなたにもこれを行うには、ブロックベースの列挙を使用することができます。

// This will eventually contain the index of the object. 
// Initialize it to NSNotFound so you can check the results after the block has run. 
__block NSInteger foundIndex = NSNotFound; 

[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
    if ([obj isKindOfClass:[MyClass class]]) { 
     foundIndex = idx; 
     // stop the enumeration 
     *stop = YES; 
    } 
}]; 

if (foundIndex != NSNotFound) { 
    // You've found the first object of that class in the array 
} 

あなたは、アレイ内のクラスのこの種の複数のオブジェクトを持っている場合は、例を少し微調整する必要がありますが、これはあなたが何ができるかのアイデアを与える必要があります。

この高速列挙の利点は、オブジェクトのインデックスも返すことができるということです。また、enumerateObjectsWithOptions:usingBlock:を使用した場合は、これを同時に検索するオプションを設定することができますので、スレッドの列挙を自由にするか、逆に配列を検索するかどうかを選択します。

ブロックベースのAPIはより柔軟です。彼らは新しくて複雑に見えますが、一度使い始めると簡単に持ち上げることができます。そして、どこにでもそれらを使用する機会が見え始めます。

+0

変数を指定して列挙を停止することを除けば、ブロックベースの方法を使用する利点は何ですか? – futureelite7

+0

-1の代わりにNSNotFoundを使用します。 – NSResponder

+0

@NSResponder - 良いキャッチ - ありがとう。 – Abizern

7

あなたは、配列をループし、高速列挙を使用し、クラスを確認することができます。

BOOL containsClass = NO; 

for (id object in array) { 
    if ([object isKindOfClass:[MyClass class]]) { 
     containsClass = YES; 
     break; 
    } 
} 
8

NSPredicateでこれを行うことができます。

NSPredicate *p = [NSPredicate predicateWithFormat:@"self isKindOfClass: %@", 
                 [NSNumber class]]; 
NSArray *filtered = [identifiers filteredArrayUsingPredicate:p]; 
NSAssert(filtered.count == identifiers.count, 
     @"Identifiers can only contain NSNumbers."); 
関連する問題