2010-11-09 7 views
6

Ich habe gerade mit dem Lernen von Objective-C begonnen und eine kleine Kompass-App erstellt, die eine Richtung anzeigt, wenn sie in eine Reihe von Überschriften fällt. Es funktioniert gut, aber ich frage mich, ob es eine prägnantere Möglichkeit gibt, es mit NSRange zu schreiben. Nach vielem Hinsehen scheint es, als ob NSRange mehr für String-Funktionen als für Zahlen verwendet wird.Wie kann ich NSRange mit Ganzzahlen verwenden, um meinen Code zu vereinfachen?

Ich habe versucht, eine Instanz von NSRange mein Ausgangspunkt, um dies prägnanter zu machen, konnte ich nicht herausfinden, die Funktion, die finden würde, wenn eine Zahl innerhalb einer NSRange fällt.

Bin ich hier auf dem richtigen Weg, oder mache ich das ausführlicher, als es sein muss?

Vielen Dank im Voraus ..

Hier wurde mein Punkt, den Code für den Versuch zu verkürzen, bis Abspringen failed:

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

Hier ist mein aktueller Code ist (funktioniert):

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

} 

Antwort

3

mache ich das ausführlicher, als es sein muss?

Ja. Wenn Sie numerische Operationen ausführen möchten, vermeiden Sie NSNumber. Die NSNumber-Klasse existiert nur, weil Objective-C-Auflistungen wie NSArray, NSDictionary usw. nur Objective-C-Objekte enthalten können. Andernfalls sollten Sie immer Ebene verwenden int oder NSInteger oder CGFloat oder double usw.

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. 

Sie brauchen nicht NSRange zu verwenden.

+1

es ist im allgemeinen besser in Cocoa und Cocoa touch den architekturunabhängige NSInteger und NSUInteger statt int zu verwenden. – Chuck

+0

@Chuck: Richtig. Aber OP verwendet '+ numberWithInt:' also behalte ich den 'int' im Code. – kennytm

+0

Danke, @KennyTM. Viel sauberer jetzt. @Chuck - nahm Ihren Tipp auf NSUInteger und benutzte das auch. Ich habe anfangs numberWithInt verwendet: weil es keine Ausnahme ausgelöst hat, also habe ich es behalten. –

0

Ein Bereich benötigt einen Ort und eine Länge. Wenn Sie also 80 bis 100 Grad für einen östlichen Bereich haben möchten, können Sie NSMakeRange (80, 20) verwenden. Das würde eine Reichweite von 80 Grad erzeugen und 20 Grad umfassen.

9

kommt spät zur Party, aber die folgenden funktionieren würde, und ich glaube, die Verwendung von Bereichen machen:

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

etc. etc.

0

Wenn Sie eine integrierte Nutzung der NSRange Struktur zu wollen, ich habe es für den Vergleich Teile von Arrays nützlich gefunden:

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;