Почему containsObject не работает с копией NSSet NSMutableSet? - PullRequest
0 голосов
/ 27 февраля 2020

У меня проблема с созданием копии набора изменяемого набора, а затем с ошибкой containsObject для (новой) копии набора. Например:

NSString *sameID = @"XYZ";

Затем в главном потоке / иногда в другом потоке:

[mutableSet addObject:sameID];
NSLog(@"adding Object: %@", sameID);

Затем в фоновом потоке, всегда после (я подтвердил с регистрацией, что) добавлен sameID:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
    NSSet<NSString *> *newSet = self.mutableSet.copy;
    if ([newSet containsObject:sameID]) {
      // do stuff
    }
});

При просмотре с точкой останова:

1. po [newSet containsObject:sameID] // returns NO
2. po [self.mutableSet containsObject:sameID] // returns YES

Я проверял, что для строки sameID нет дополнительных или скрытых пробелов. AFAIK containsObject для наборов, содержащих NSString, использует isEqual, который не имеет / не должен иметь значения, если строки имеют разные указатели, верно?

Редактировать: Некоторая дополнительная информация: строки NSSt, которые добавляются в mutableSet, происходят на разные темы, но всегда перед созданием копии newSet. Создание и проверка newSet выполняется в фоновом потоке, поэтому я копирую mutableSet (и с ведением журнала я вижу, что это всегда происходит после добавления строки (ей) в mutableSet). Таким образом, я вижу в операторах журнала, что строка (sameID) была добавлена ​​в mutableSet, затем в фоновом потоке я копирую mutableSet в набор и быстро проверяю этот набор для той же строки (sameID), а ее там нет.

Edit2: я протестировал приведенный ниже код, и он прошел для меня, однако, когда я попытался реализовать то же решение, что и выше, он по-прежнему имеет тот же результат (mutableSet содержит строку, а newSet - нет).

import XCTest
import Foundation

class CustomObj: NSObject {
    let id: String

    init(id: String) { self.id = id }

    override func isEqual(_ object: Any?) -> Bool {
        if let other = object as? CustomObj {
            return self.id == other.id
        } else {
            return false
        }
    }

    override var hash: Int {
        return id.hashValue
    }
}

func testSetStrings() {
    let set = NSMutableSet(object: CustomObj(id: "String-1"))
    let copySet: Set<CustomObj> = set.copy() as! Set<CustomObj>

    let customObjForTest = CustomObj(id: "String-1")

    XCTAssertTrue(set.contains(customObjForTest), "Does Not Contain")
    XCTAssertTrue(copySet.contains(customObjForTest), "Copy Does Not Contain")
}

testSetStrings()
...