NSSet NSNumbers - метод-член всегда равен нулю - PullRequest
6 голосов
/ 08 ноября 2011


Я хочу иметь простой NSSet, который загружается с некоторыми номерами NSNumbers, а затем выяснить, добавлены ли эти числа в набор или нет. Когда я делаю это:

NSMutableSet *set = [[NSMutableSet alloc] init];
NSNumber *num1 = [NSNumber numberWithInt:5];
NSNumber *num2 = [NSNumber numberWithInt:5];
[set addObject:num1];
if([set member:num2]){
   // something...
}

Проблема в том, что член всегда возвращает nil (если false), даже если эти числа одинаковы. Метод isEqual возвращает true. Так

if([num1 isEqual:num2]){
   // correct
}

работает ...
В документации я читал, что метод member использует isEqual, поэтому я не знаю, в чем проблема ... Спасибо за любой совет.

Ответы [ 4 ]

5 голосов
/ 11 июня 2015

Когда вы используете NSArray, вам нужно сравнивать значения вместо самих объектов.Вместо использования NSArray вы можете использовать NSMutableIndexSet.Это позволяет сравнивать значения с несколькими меньшими шагами.

//during init, add some numbers
NSMutableIndexSet *tSet = [[NSMutableIndexSet alloc] init];
NSUInteger exampleValue = 7;
[tSet addIndex:exampleValue];
exampleValue = 42;
[tSet addIndex:exampleValue];

//...later on
//look to see if numbers are there
if ([tSet containsIndex:7]){
    NSLog(@"7 exists!");
}
if ([tSet containsIndex:8]){
    NSLog(@"8 exists!");
}

Вывод: 7 существует!

4 голосов
/ 08 ноября 2011

Необходимо сравнивать значения NSNumbers, а не объектов.

Вы можете использовать objectsPassingTest:

Пример:

NSMutableSet *set = [[NSMutableSet alloc] init];
NSNumber *num1 = [NSNumber numberWithInt:5];
NSNumber *num2 = [NSNumber numberWithInt:5];
NSNumber *num3 = [NSNumber numberWithInt:3];
[set addObject:num1];

NSSet *filteredSet;
filteredSet = [set objectsPassingTest:^(id obj,BOOL *stop){
    return [obj isEqualToNumber:num2];
}];
NSLog(@"Contains num2: %@", (filteredSet.count == 1) ? @"YES" : @"NO");

filteredSet = [set objectsPassingTest:^(id obj,BOOL *stop){
    return [obj isEqualToNumber:num3];
}];
NSLog(@"Contains num3: %@", (filteredSet.count == 1) ? @"YES" : @"NO");

Вывод NSLog:

Contains num2: YES
Contains num3: NO

Или, если желательно использовать предикаты:

filteredSet = [set filteredSetUsingPredicate:[NSPredicate predicateWithFormat:@"SELF == %@", num2]];
NSLog(@"Contains num2: %@", (filteredSet.count == 1) ? @"YES" : @"NO");

filteredSet = [set filteredSetUsingPredicate:[NSPredicate predicateWithFormat:@"SELF == %@", num3]];
NSLog(@"Contains num3: %@", (filteredSet.count == 1) ? @"YES" : @"NO");
2 голосов
/ 18 февраля 2013

Код работает, так как Привет слово записывается в журнал, когда я его запускаю

 NSMutableSet *set = [[NSMutableSet alloc] init];
 NSNumber *num1 = [NSNumber numberWithInt:5];
 NSNumber *num2 = [NSNumber numberWithInt:5];
 [set addObject:num1];
 if([set member:num2]){
     NSLog(@"Hello, world");
  }
2 голосов
/ 08 ноября 2011

Проблема в том, что вы проверяете, являются ли num1 и num2 одним и тем же объектом. И они не. Они просто имеют одинаковое значение, но это два разных объекта с одинаковым значением.

Итак, с помощью member вы проверяете, имеют ли они одинаковый адрес в памяти.

Редактировать: Вы должны использовать compare, чтобы проверить, совпадают ли значения чисел!

...