Shawn Baek
Shawn Baek

Reputation: 1967

Objective-C Generic : NSNumber -> NSString

I'm trying to use Objective-C Generic Features.

NSArray<NSNumber *> *genericNumber = @[@42, @556, @69, @3.14];

        for (NSString *number in genericNumber){
            NSLog(@"%@ is %ld letters.", number, [number length]);

        }

But It didn't work...

Am I wrong?

Upvotes: 1

Views: 170

Answers (2)

CRD
CRD

Reputation: 53010

You first create an array:

NSArray<NSNumber *> *genericNumber = @[@42, @556, @69, @3.14];

This array contains NSNumber objects and the lightweight generics type of the array is NSArray<NSNumber *> *. The lightweight bit is important as it reminds us that Objective-C is not strongly typed at compile time, some type errors will not be found until runtime.

You then start a loop:

for (NSString *number in genericNumber){

Here you are telling the compiler that number will be an NSString reference. However the array contains NSNumbers but as the compiler cannot in general check that (as its Objective-C) the compiler trusts you and stores a reference to an NSNumber, not a reference to an NSString, into number. So here you have a type error which the compiler doesn't spot and which will cause a problem at runtime.

You continue:

   NSLog(@"%@ is %ld letters.", number, [number length]);

Here the call [number length] will pass the compiler, as it believes number references an NSString, but will fail at runtime as number references an NSNumber and there is no length method on NSNumber.

You can fix these as follows:

for (NSNumber *number in genericNumber)      // type number correctly
{
   NSString *asText = [number stringValue];  // obtain the number value as text
   NSLog(@"%@ has %ld chars", asText, asText.length);
}

HTH

Upvotes: 1

l&#39;L&#39;l
l&#39;L&#39;l

Reputation: 47284

It's probably better keep the number as just that, and use stringWithFormat to get the length:

NSArray *genericNumber = @[@42, @556, @69, @3.14];

for (NSNumber *number in genericNumber) {
    int length = [[NSString stringWithFormat:@"%@", number] length];
    NSLog(@"%@ is %d chars.", number, length);
}

Output:

42 is 2 chars.
556 is 3 chars.
69 is 2 chars.
3.14 is 4 chars.

Upvotes: 1

Related Questions