2010-11-09 51 views
6

我刚开始学习Objective-C,并制作了一个小罗盘应用程序,该应用程序将显示一个方向,当它落入一系列标题时。它工作得很好,但我想知道是否有更简洁的方式使用NSRange来编写它。经过大量的研究,似乎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:@"-"]; 

} 

回答

3

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

是的。当你想做数字操作时,避免使用NSNumber。 NSNumber类的存在只是因为像NSArray,NSDictionary等Objective-C集合只能存放Objective-C对象。否则,你应该总是使用纯intNSIntegerCGFloatdouble

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。

+1

它通常更好的可可和可可触摸使用的体系结构无关NSInteger的和NSUInteger,而不是int类型。 – Chuck 2010-11-09 22:11:45

+0

@Chuck:对。但OP使用'+ numberWithInt:',所以我保留'int'在代码中。 – kennytm 2010-11-09 22:13:33

+0

谢谢,@KennyTM。现在更清洁。 @Chuck - 把你的小费放在NSUInteger上,并使用它。我最初使用numberWithInt:因为它没有抛出异常,所以我保留它。 – 2010-11-10 02:44:33

0

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

9

即将迟到了,但下面会工作,并利用范围,我相信:

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

等等,等等

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;