Reputation: 1967
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
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 NSNumber
s 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
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