Каков наилучший способ проверить, содержит ли NSArray объект определенного типа класса? containsObject:
, похоже, проверяет равенство, тогда как я ищу проверку равенства isKindOfClass:
.
Как проверить, содержит ли NSArray объект определенного класса?
Ответ 1
Вы также можете использовать перечисление на основе блоков.
// 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 на основе блоков более гибкий. Хотя они выглядят новыми и сложными, их легко подобрать, как только вы начнете их использовать, - и затем вы начнете видеть возможности использовать их повсюду.
Ответ 2
Вы можете использовать быстрое перечисление для циклического прохождения массива и проверить класс:
BOOL containsClass = NO;
for (id object in array) {
if ([object isKindOfClass:[MyClass class]]) {
containsClass = YES;
break;
}
}
Ответ 3
Вы можете сделать это с помощью NSPredicate.
NSPredicate *p = [NSPredicate predicateWithFormat:@"self isKindOfClass: %@",
[NSNumber class]];
NSArray *filtered = [identifiers filteredArrayUsingPredicate:p];
NSAssert(filtered.count == identifiers.count,
@"Identifiers can only contain NSNumbers.");