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ür isEqual 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.

InformationsquelleAutor Aaron Hayman | 2013-10-24
Schreibe einen Kommentar