2010-11-09 13 views
6

Właśnie zacząłem uczyć się Objective-C i stworzyłem małą aplikację kompasową, która wyświetli kierunek, gdy znajdzie się w zakresie nagłówków. Działa dobrze, ale zastanawiam się, czy istnieje bardziej zwięzły sposób zapisu go przy użyciu NSRange. Po wielu poszukiwaniach wydaje się, że jest on używany raczej dla funkcji łańcuchowych niż liczb.Jak mogę użyć NSRange z liczbami całkowitymi, aby uprościć mój kod?

Próbowałem uczynić instancję z NSRange moim punktem wyjścia, aby uczynić to bardziej zwięzłym, nie mogłem wyśledzić funkcji, która mogłaby się znaleźć, gdyby liczba przypadała na NSRange.

Czy jestem tu na właściwym tropie, czy też sprawiam, że jest to bardziej szczegółowe niż to konieczne?

góry dzięki ..

Tu był mój failed skacząc punkt za próbę skrócenia się kod:

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

Oto mój aktualny kod (działa poprawnie):

- (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:@"-"]; 

} 

Odpowiedz

3

Czy to bardziej szczegółowe niż to konieczne?

Tak. Jeśli chcesz wykonywać operacje numeryczne, unikaj NSNumber. Klasa NSNumber istnieje tylko dlatego, że zbiory Objective-C, takie jak NSArray, NSDictionary itp., Mogą zawierać tylko obiekty Objective-C. W przeciwnym razie, należy zawsze używać zwykłego int lub NSInteger lub CGFloat lub double itp

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. 

Nie trzeba używać NSRange.

+1

to generalnie lepiej w Cocoa i Cocoa touch używać architektura niezależne NSInteger i NSUInteger zamiast int. – Chuck

+0

@Chuck: Racja. Ale OP używa '+ numberWithInt:', więc trzymam 'int' w kodzie. – kennytm

+0

Dzięki, @KennyTM. Teraz dużo czystszy. @Chuck - wziął twój napiwek na NSUInteger i użył tego też. Początkowo użyłem numberWithInt: ponieważ nie wyrzucił wyjątku, więc go zatrzymałem. –

0

Zasięg zależy od lokalizacji i długości. Więc jeśli chcesz 80 do 100 stopni dla wschodniego zasięgu, możesz użyć NSMakeRange (80, 20). To by tworzyło zakres zaczynający się od 80 stopni, obejmujący 20 stopni.

9

Coming późno do partii, ale dodaje będą pracować i korzystać z zakresów wierzę:

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

itp itd

0

Jeśli chcą bardziej zintegrowane wykorzystanie struktury NSRange, znalazłem to przydatne do porównywania części tablic:

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; 
Powiązane problemy