6

我刚刚开始学习 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:@"-"];

}
4

4 回答 4

10

参加聚会迟到了,但我相信以下方法会起作用并利用范围:

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

等等等等

于 2013-01-10T15:42:43.390 回答
3

我是否让这比它需要的更冗长?

是的。当你想做数值运算时,避免使用 NSNumber。NSNumber 类的存在只是因为 NSArray、NSDictionary 等 Objective-C 集合只能保存 Objective-C 对象。否则,您应该始终使用普通的intorNSIntegerCGFloatordouble等​​。

 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。

于 2010-11-09T22:02:15.953 回答
0

如果您想要更集成地使用 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;
于 2014-02-04T17:46:58.247 回答
0

范围需要一个位置和一个长度。因此,如果您想要东部范围的 80 到 100 度,您可以使用 NSMakeRange(80, 20)。这将创建一个范围从 80 度开始,跨越 20 度。

于 2010-11-09T22:01:47.063 回答