NSSet of the NSNumbers method - member is always zero


I want to have a simple NSSet that is loaded by some NSNumbers, and then finds out if these numbers are added to the set or not. When I do this:

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

The problem is that the member always returns nil (if is false), even if these numbers are the same. isEqual returns true. So

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

works...
I read in the docs that the member method uses isEqual, so I don't know what the problem is ... Thanks for any advice.

+6
source share
4 answers

The problem is that you are checking if the num1 and num2 tags are the same object. And this is not so. They have the same value, but they are two different objects with the same value.

So, what do you check with member to see if they have the same address in memory.

Edit: you should use compare to check if the numbers are the same!

+2
source

You must compare the values ​​of NSNumbers, not the objects.

You can use objectsPassingTest:

Example:

 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 Output:

 Contains num2: YES Contains num3: NO 

Or, if you want to use predicates:

 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"); 
+4
source

When you use NSArray, you need to compare the values ​​instead of the objects themselves. Instead of using NSArray, you can use NSMutableIndexSet. This allows you to compare values ​​with a few smaller steps.

 //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!"); } 

Conclusion: 7 exists!

+4
source

The code works because the word Hello is logged at startup

  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
source

Source: https://habr.com/ru/post/901028/


All Articles