У меня проблема с созданием копии набора изменяемого набора, а затем с ошибкой 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()