Как я могу использовать NSRange с целыми числами, чтобы упростить код?

Я только начал изучать Objective-C и сделал небольшое приложение-компас, которое будет отображать направление, когда оно попадает в диапазон заголовков. Он работает нормально, но мне интересно, есть ли более сжатый способ написать это с помощью NSRange. После долгих поисков кажется, что NSRange больше используется для строковых функций, чем для чисел.

Я попытался сделать экземпляр NSRange моей отправной точкой, чтобы сделать его более кратким, я не мог отследить функцию, которая могла бы найти, если число попадет в NSRange.

Я на правильном пути, или я делаю это более подробным, чем нужно?

Заранее спасибо..

Вот моя неудачная отправная точка при попытке сократить код:

// If heading falls within this range, then display "S" for south    
NSRange eastenRange = NSMakeRange (80, 100); 
NSRange southernRange = NSMakeRange (170, 190); 
etc...

Вот мой текущий код (отлично работает):

- (void)locationManager:(CLLocationManager *)manager 
    didUpdateHeading:(CLHeading *)newHeading
{
 // Define and display the heading
 NSNumber *theHeading = [NSNumber numberWithInt:[newHeading trueHeading]];
 [headingLabel setText:[NSString stringWithFormat:@"%@°", theHeading]];

 // Define the range of directions
 NSNumber *northLowerRange = [NSNumber numberWithInt:10];
 NSNumber *northUpperRange = [NSNumber numberWithInt:350];

 NSNumber *eastLowerRange = [NSNumber numberWithInt:80];
 NSNumber *eastUpperRange = [NSNumber numberWithInt:100];

 NSNumber *southLowerRange = [NSNumber numberWithInt:170];
 NSNumber *southUpperRange = [NSNumber numberWithInt:190];

 NSNumber *westLowerRange = [NSNumber numberWithInt:260];
 NSNumber *westUpperRange = [NSNumber numberWithInt:280];


 // If the heading falls within the correct ranges, then display the direction
 if ([northLowerRange compare:theHeading] == NSOrderedDescending || [northUpperRange compare:theHeading] == NSOrderedAscending)
  [directionLabel setText:@"N"];
 else if ([eastLowerRange compare:theHeading] == NSOrderedAscending && [eastUpperRange compare:theHeading] == NSOrderedDescending)
  [directionLabel setText:@"E"];
 else if ([southLowerRange compare:theHeading] == NSOrderedAscending && [southUpperRange compare:theHeading] == NSOrderedDescending)
  [directionLabel setText:@"S"];
 else if ([westLowerRange compare:theHeading] == NSOrderedAscending && [westUpperRange compare:theHeading] == NSOrderedDescending)
  [directionLabel setText:@"W"];
 else
  [directionLabel setText:@"-"];

}

person Matt Miller    schedule 09.11.2010    source источник


Ответы (4)


я делаю это более подробным, чем нужно?

да. Если вы хотите выполнять числовые операции, избегайте NSNumber. Класс NSNumber существует только потому, что коллекции Objective-C, такие как NSArray, NSDictionary и т. Д., Могут содержать только объекты Objective-C. В противном случае вы всегда должны использовать простые int или NSInteger, CGFloat или double и т. Д.

 int heading = [newHeading trueHeading];
 headingLabel.text = [NSString stringWithFormat:@"%d°", heading];

 if (10 < heading || heading > 350)
    directionLabel.text = @"N";
 else if (80 < heading && heading < 100)
    directionLabel.text = @"E";
 // and so on.

Вам не нужно использовать NSRange.

person kennytm    schedule 09.11.2010
comment
Обычно в Cocoa и Cocoa Touch лучше использовать независимые от архитектуры NSInteger и NSUInteger, а не int. - person Chuck; 10.11.2010
comment
@ Чак: Верно. Но OP использует +numberWithInt:, поэтому я сохраняю int в коде. - person kennytm; 10.11.2010
comment
Спасибо, @KennyTM. Теперь намного чище. @Chuck - взял ваш отзыв о NSUInteger и тоже использовал его. Сначала я использовал numberWithInt: потому что он не генерировал исключения, поэтому я оставил его. - person Matt Miller; 10.11.2010
comment
@Chuck NSDecimalNumber также полезен при работе с числовыми значениями, которые чувствительны к десятичным значениям, например, при работе с валютой. Проверить это: stackoverflow.com/a/422513/1152596 - person The dude; 07.11.2013

Я опаздываю на вечеринку, но я считаю, что следующее будет работать и использовать диапазоны:

NSRange easternRange = NSMakeRange (80, 20); 
NSRange southernRange = NSMakeRange (170, 20); 

NSInteger heading = 92;
if (NSLocationInRange(heading,easternRange)) {
  NSLog(@"Heading Easterly.");
} else if (NSLocationInRange(heading,southernRange)) {
  NSLog(@"Heading southerly.");
}

и т. д. и т. д.

person Diziet    schedule 10.01.2013

Диапазон принимает местоположение и длину. Итак, если вы хотите от 80 до 100 градусов для восточного диапазона, вы можете использовать NSMakeRange (80, 20). Это создаст диапазон от 80 градусов до 20 градусов.

person Donald    schedule 09.11.2010

Если вам нужно более интегрированное использование структуры NSRange, я счел ее полезной для сравнения частей массивов:

NSRange aRange = NSRangeFromString([NSString stringWithFormat:@"{0:%d}",items.count]);
NSIndexSet* aSet = [NSIndexSet indexSetWithIndexesInRange:aRange];
NSIndexSet *hasNotBeenReadSet = [items indexesOfObjectsAtIndexes:aSet
                                                          options:NSEnumerationConcurrent
                                                      passingTest:
                                  ^BOOL(BasicItem* obj, NSUInteger idx, BOOL *stop) {
                                    return [obj hasNotBeenRead];
                                  }];

int numberOfUnreadItems = hasNotBeenReadSet.count;
person Brooks Hanes    schedule 04.02.2014