NSArray containsObject nicht funktioniert wie beworben
So, die Apple-Dokumentation sagt über containsObject
:
Dieser Methode bestimmt, ob anObject ist in dem array von
senden Sie eine isEqual: - message an jeden der array-Objekte (und
vorbei anObject als parameter für jede isEqual: - message).
Finden Sie diese docs hier.
Allerdings erlebe ich fast das genaue Gegenteil bewirken. Anstatt isEqual:
für jedes Objekt in meinem array, das Objekt, die ich immer geschickt die isEqual:
Nachricht für jedes Objekt im array.
Zum Beispiel habe ich zwei Klassen: FlxSort
und FlxFieldKey
. Ein FlxSort
Klasse enthält ein Feld Schlüssel, und ich habe überschrieben, die isEqual:
true zurück, wenn es vergingen ein FlxFieldKey
Objekt, das mit dem Schlüssel überein, die er hält. Dies sollte in der Theorie können mich zu überprüfen, ob eine FlxSort
Objekt ist in dem array mit einem bestimmten Schlüssel. Allerdings FlxFieldKey
nicht (und sollte nicht) bewusst FlxSort
Objekt, so wird es immer false zurückgeben, wenn es zur Verfügung gestellt eine FlxSort
Objekt in seiner isEqual
Nachricht. Also in dem code unten, würde ich erwarten, dass jedes Objekt in currentSorts
gesendet werden, die isEqual:
Nachricht für jede Taste in _avialableKeys
. Stattdessen jede Taste in _availableKeys
gesendet wird, die isEqual:
Nachricht. Ich habe dies sowohl mit der Protokollierung und Haltepunkte.
NSMutableArray *keys = [NSMutableArray arrayWithCapacity:_avialableKeys.count];
NSArray *currentSorts = _sortGroup.sorts;
for (FlxFieldKey *key in _avialableKeys){
if (![currentSorts containsObject:key]){
[keys addObject:key];
}
}
Bin ich hier etwas fehlt?
Update
Auch wenn ich gefragt wurde über [NSArray containsObject:]
bekam ich viel feedback über meine Umsetzung der asymmetrischen Geschlechter. So will ich klären, dass meine Umsetzung war ein experiment, geboren aus Neugier. Der original-code nicht verwenden containsObject
an alle:
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];
}
}
War ich neugierig, wenn ich könnte rig containsObject
zu arbeiten in der oben genannten situation. Natürlich, wie bereits schon betont wurde von mehreren Leuten, die das erstellen der asymmetrischen Geschlechter ist eine schlechte Idee und geht direkt gegen apples Empfehlungen. Ich könnte ändern Sie die isEqual:
Methode in der FlxFieldKey
zu berücksichtigen FlxSort
Objekte, die würde wiederherzustellen, die symmetrische Gleichheit zwischen zwei Klassen... irgendwie. Sie konnte sich noch am Ende mit A == B, A == C, aber B != C. Und das bleibt immer noch die hash
problem (Sie müssen die gleichen sein).
Lassen Sie mich wiederholen: Sie nicht wollen, dies zu tun (asymmetrische Gleichheit). Zumindest nicht in der Produktion code. Ich bin nur herum hier zu sehen, was ich kann tun, nicht das, was ich sollte tun. Ich gebe zu, es war unverantwortlich von mir nicht zu klären, diese in der ursprünglichen Frage als weniger erfahrene Entwickler können denken, dass diese Art der Umsetzung ist in Ordnung, zu tun. Ich entschuldige mich für diese.
Und ja, werde ich wohl einen Bericht, eine Dokumentation, ein Fehler im Radar, sobald ich kann dennoch den Mut aufbringen, geben Sie die Apple-bug reporter wieder...
- Sollten Sie wahrscheinlich tun, die in Ihrer eigenen Schleife und mit Ihrem eigenen Vergleich Methode. Wie es heißt, Sie würden sich auf Apple-Implementierung-details...
- Ja, ich habe schon gearbeitet, um es mit meinen eigenen loop, aber es dauerte eine kleine Weile, um herauszufinden, was Los war. Ich dachte nur, es sei sicher davon ausgehen, dass es funktioniert, wie Sie sagte, es funktionierte. Ich stellte die Frage weil ich will, um sicherzustellen, dass ich nicht etwas fehlt.
- Das ist unglaublich gefährlich. Sie haben eine situation geschaffen, wo A == B aber B != A. Das ist Undefiniertes Verhalten für viele algorithmen. Sollten Sie einen anderen Ansatz.
- Ich habe bereits implementiert, ein anderer Ansatz. Diese Art der Verwendung
isEqual
war mehr ein experiment. Aber du hast Recht. Ich überprüfte die Dokumente fürisEqual
und die hashes müsste gleich sein, was Sie nicht sind. - Sollten Sie einen bug-Bericht. Die meisten wahrscheinlich das Ergebnis der bug-report wäre eine Dokumentation ändern.
- Erwägen Sie die Verwendung -indexOfObjectPassingTest: oder -enumerateObjectsUsingBlock: anstatt -isEqual: und -containsObject: .
- So, wir haben iOS8 und das gleiche Problem existiert in der doc. Apple hat immer zu reagieren, um Ihre bug-report? Interessanterweise Java collections verwendet, um es zu implementieren als Apple-Staaten, die hier den Weg zurück in 1.4 oder vielleicht 1.3, und dann änderten Sie deren Umsetzung entsprechen, was Sie beobachtet haben in NSArray. Wirklich ärgerlich an der Zeit.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Du hast Recht, es ist eine Diskrepanz zwischen der Durchführung und der Dokumentation, und Sie sollten melden Sie einen Fehler auf dem radar.
Aber es diente dem Zweck der Hervorhebung ein design-Problem in Ihrer Implementierung.
Die Reihenfolge der Vergleich sollte wirklich egal, wie die Gleichheit
sollte immer true sein, es sei denn, Sie absichtlich ausführen möchten, in Schwierigkeiten.
Dass sagte Sie ich glaube, eine
NSSet
wäre viel besser geeignet für die Art von Aufgabe, da diecontainsObject:
- Vorgang ausgeführt wird, in konstanter Zeit, im Gegensatz zu linear-im Falle vonNSArray
. In diesem Fall würden Sie auch außer Kraft setzen müssenhash
Methode.Ich weiß nicht, dass dies ist, was tatsächlich geschieht, aber die Umsetzung
containsObject:
als (lose):bedeutet, dass
testObj
'sisEqual:
- Implementierung zwischengespeichert werden können und nicht direkt aufgerufen, sondern als die Nachricht ausgelöst durchobjc_msgSend()
jeder Zeit. DaNSArray
s heterogener, wäre es nicht möglich, den cache bei jedem Anruf, wenn der Vergleich war die andere Weise herum, wie die docs sagen, es ist.Es ist nur eine kleine Leistung zu gewinnen gibt, können sich zu rechtfertigen für die großen arrays.
Sollten Sie wahrscheinlich die Datei eine doc-bug, obwohl als Rob Napier wies darauf hin, dies ist nur ein problem, wenn Sie die Gleichheit der asymmetrischen, das ist eine problematische Idee in sich selbst.