Objective-C Kategorie Frage
-
25-09-2019 - |
Frage
Ich habe eine benutzerdefinierte erstellt Sortierung durch eine neue Kategorie für die NSString
Klasse zu schaffen. Unten ist mein Code.
@implementation NSString (Support)
- (NSComparisonResult)sortByPoint:(NSString *)otherString {
int first = [self calculateWordValue:self];
int second = [self calculateWordValue:otherString];
if (first > second) {
return NSOrderedAscending;
}
else if (first < second) {
return NSOrderedDescending;
}
return NSOrderedSame;
}
- (int)calculateWordValue:(NSString *)word {
int totalValue = 0;
NSString *pointPath = [[NSBundle mainBundle] pathForResource:@"pointvalues"ofType:@"plist"];
NSDictionary *pointDictionary = [[NSDictionary alloc] initWithContentsOfFile:pointPath];
for (int index = 0; index < [word length]; index++) {
char currentChar = [word characterAtIndex:index];
NSString *individual = [[NSString alloc] initWithFormat:@"%c",currentChar];
individual = [individual uppercaseString];
NSArray *numbersForKey = [pointDictionary objectForKey:individual];
NSNumber *num = [numbersForKey objectAtIndex:0];
totalValue += [num intValue];
// cleanup
individual = nil;
numbersForKey = nil;
num = nil;
}
return totalValue;
}
@end
Meine Frage ist, ob ich einen Punkt Wörterbuch erstellen den Punktwert mit jedem Zeichen in dem auf einem plist basierten Alphabet zugeordnet zu bestimmen. Dann in meinen Ansicht-Controller, ich nenne
NSArray *sorted = [words sortedArrayUsingSelector:@selector(sortByPoint:)];
zu meinem Tisch von Worten durch ihre Punktwerte zu sortieren. Allerdings rief ein neues Wörterbuch jedes Mal, wenn die -sortByPoint:
Verfahren zu schaffen, ist äußerst ineffizient. Gibt es eine Möglichkeit, die pointDictionary zu erstellen vorher und es zu verwenden, für jeden weiteren Aufruf in der -calculateWordValue:
?
Lösung
Dies ist ein Job für das Schlüsselwort static. Wenn Sie dies tun:
static NSDictionary *pointDictionary = nil
if (pointDictionary==nil) {
NSString *pointPath = [[NSBundle mainBundle] pathForResource:@"pointvalues" ofType:@"plist"];
pointDictionary = [[NSDictionary alloc] initWithContentsOfFile:pointPath];
}
pointDictionary
wird für die gesamte Lebensdauer Ihrer App hartnäckig sein.
Eine weitere Optimierung ist es, einen Cache von Partituren aufzubauen, indem diese gegen jedes Ihrer Worte mit:
[dict setObject:[NSNumber numberWithInt:[word calculateWordValue:word]] forKey:word];
Dann die keysSortedByValueUsingSelector:
Methode verwenden, um Ihre Liste von Wörtern zu extrahieren (beachten Sie chould der Wähler vergleichen werden :, da die Objekte verglichen werden, sind die NSNumbers).
Schließlich wird das Wort Argument auf Ihrer Methode ist überflüssig. Verwenden Sie selbst statt:
-(int)calculateWordValue {
...
for (int index = 0; index < [self length]; index++)
{
char currentChar = [self characterAtIndex:index];
...
}
...
}
Andere Tipps
Ändern Sie Ihre sortByPoint:(NSString *) otherString
Methode das Wörterbuch als Parameter zu nehmen, und übergeben Sie Ihre bereits erstellten Wörterbuch.
sortByPoint:(NSString *)otherString withDictionary:(NSDictionary *)pointDictionary
EDIT: Wird nicht wegen Verwendung in sortedArrayWithSelector arbeiten. Apologies. Stattdessen können Sie besser dran, eine Wrapper-Klasse für Ihren Punkt Wörterbuch als Singleton zu schaffen, die Sie dann einen Verweis auf jede Zeitfunktion läuft Ihre Art erhalten.
In calculateWordValue
:
NSDictionary *pointDictionary = [[DictWrapper sharedInstance] dictionary];
DictWrapper
hat eine NSDictionary als Eigenschaft, und eine Klassenmethode sharedInstance
(die Singleton zurückzukehren. Sie haben dieses Wörterbuch zu setzen und Pre-initialisieren, bevor Sie tun Sie zuerst sortieren.