Belle
Belle

Reputation: 293

NSNumber claims to be NSString

I am getting the warning Comparison of distinct pointer types ('NSString *' and 'NSNumber *') in this line of code:

if(beacon.beaconIdentifier == self.identifier) {
  // do something
}

Both should contain an NSNumber. The object beacon is a CLBeacon. self.identifier is a NSNumber. Other possibly relevant code:

CLBeacon category

@interface CLBeacon ();
@property(nonatomic, strong) NSNumber *beaconIdentifier;
@end

static char const *const MyBeaconIdentifier = "MyBeaconIdentifier";

....

- (CLBeacon *)initWithJSON:(NSDictionary *)json {
  self = [super init];
  if (self) {
    ...
    self.beaconIdentifier = json[@"id"];
  }
  return self;
}

- (void) setBeaconIdentifier:(NSNumber *)beaconIdentifier {
  objc_setAssociatedObject(self, MyBeaconIdentifier, beaconIdentifier, OBJC_ASSOCIATION_RETAIN);
}

- (NSNumber *)beaconIdentifier {
   return objc_getAssociatedObject(self, MyBeaconIdentifier);
}

json[@"id"] always only contains numbers. Besides the warning, everything runs as it should. What is causing my problem and what could possibly solve it?

Thanks to a couple great responses, I managed to solve the warning. Still, I would like to know what caused it, if that is possible.

beacon.beaconIdentifier.class logs _NSCFNumber, just as self.identifier does.

Upvotes: 1

Views: 221

Answers (2)

zoul
zoul

Reputation: 104105

First, you are using pointer equality (“do these pointers point to the same address?”) where you want to use object equality (“are the objects pointed to by these pointers considered equal?”). Simply call -isEqual: instead of using == to fix this. [Comparing using == could work for NSNumbers since they are tagged pointers, but you shouldn’t do it anyway.]

Second, if the compiler complains of mismatched types, beaconIdentifier and self.identifier can’t really both be declared as NSNumbers, there has to be an NSString somewhere.

Upvotes: 1

Nishant
Nishant

Reputation: 12617

You say json[@"id"] contains a number, but that is not known at compile-time. Hence the warning. Its only at run-time that it will be identified as NSNumber by the compiler.

To check equality of NSNumber, try this code

if([beacon.beaconIdentifier isEqualToNumber:self.identifier]) {
  // do something
}

Upvotes: 1

Related Questions