Таким образом, документация Apple, говорит, что это о containsObject
:NSArray containsObject не работает как рекламируется
Этот метод определяет anObject присутствует в массиве с помощью отправки IsEqual в: сообщение для каждого из объектов массива (и передавая anObject в качестве параметра для каждого isEqual: message).
Вы можете найти эти документы here.
Однако, я испытываю почти полный противоположный эффект. Вместо отправки isEqual:
каждому объекту в моем массиве объект, который я предоставляю, получает сообщение isEqual:
для каждого объекта в массиве.
Например, у меня есть два класса: FlxSort
и FlxFieldKey
. Класс FlxSort
содержит ключ поля, и я переопределил isEqual:
, чтобы вернуть true, если он передал объект FlxFieldKey
, который соответствует ключу, который он удерживает. Теоретически это должно позволить мне проверить, присутствует ли в массиве объект FlxSort
с определенным ключом. Однако FlxFieldKey
не является (и не должен) знать объект FlxSort
, поэтому он всегда будет возвращать значение false, если в сообщении FlxSort
содержится сообщение isEqual
. Поэтому в приведенном ниже коде я ожидаю, что каждый объект в currentSorts
будет отправлен сообщение isEqual:
для каждого ключа в _avialableKeys
. Вместо этого каждый ключ в _availableKeys
отправляется сообщение isEqual:
. Я проверил это как с протоколированием, так и с точками останова.
NSMutableArray *keys = [NSMutableArray arrayWithCapacity:_avialableKeys.count];
NSArray *currentSorts = _sortGroup.sorts;
for (FlxFieldKey *key in _avialableKeys){
if (![currentSorts containsObject:key]){
[keys addObject:key];
}
}
Я пропустил что-то здесь?
Update
Хотя я спрашивал о [NSArray containsObject:]
я получил много откликов о моей реализации асимметричного равенства. Поэтому я хочу уточнить, что моя реализация была экспериментом, рожденным из любопытства. Исходный код не использовал containsObject
вообще:
NSMutableArray *keys = [NSMutableArray arrayWithCapacity:_avialableKeys.count];
NSArray *currentSorts = _sortGroup.sorts;
for (FlxFieldKey *key in _avialableKeys){
BOOL found = NO;
for (FlxSort *sort in currentSorts){
if ([sort.key isEqual:key]){
found = YES;
break;
}
}
if (!found){
[keys addObject:key];
}
}
мне было интересно, если я мог бы вышка containsObject
работать в описанной выше ситуации. Конечно, как было отмечено несколькими людьми, создание асимметричного равенства - плохая идея и идет прямо против рекомендаций Apple. I может изменить метод isEqual:
в FlxFieldKey
для учета FlxSort
объектов, которые восстановили бы симметричное равенство между двумя классами ... вид. Вы все равно можете получить A == B, A == C, но B! = C. И это все еще оставляет проблему hash
(они должны быть одинаковыми).
Повторю: Вы не хотите этого делать (асимметричное равенство). По крайней мере, не в производственном кодексе. Я просто возился здесь, видя, что я может do, не то, что я должно сделать. Я признаю, что мне было безответственно не уточнять это в первоначальном вопросе, поскольку менее опытные разработчики могут подумать, что такая реализация вполне оправдана. Прошу прощения за это.
И да, я, вероятно, сообщить об ошибке в документации Radar, как только я могу набраться смелости, чтобы войти в Apple, ошибка репортер снова ...
Возможно, вы должны сделать это в своем собственном цикле и с помощью собственного метода сравнения. Поскольку вы полагаетесь на детали реализации Apple ... – Wain
Да, я уже работал над этим с помощью своего собственного цикла, но мне потребовалось немного времени, чтобы выяснить, что происходит. Я просто подумал, что было бы безопасно предположить, что это сработало так, как они сказали, что это сработало. Я задал вопрос, потому что хочу убедиться, что я чего-то не пропущу. –
Это невероятно опасно. Вы создали ситуацию, когда A == B, но B! = A. Это неопределенное поведение для многих алгоритмов. Вы должны найти другой подход. –