Pergunta de categoria de Objective-C.
-
25-09-2019 - |
Pergunta
Eu criei uma classificação personalizada criando uma nova categoria para o NSString
classe. Abaixo está o meu código.
@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
Minha pergunta é se eu crio um dicionário de pontos para determinar o valor de ponto associado a cada caractere no alfabeto com base em um plista. Então, no meu controlador de visualização, eu ligo
NSArray *sorted = [words sortedArrayUsingSelector:@selector(sortByPoint:)];
Para classificar minha tabela de palavras pelos valores pontuais deles. No entanto, criando um novo dicionário cada vez que o -sortByPoint:
O método é chamado é extremamente ineficiente. Existe uma maneira de criar o PointDictionary de antemão e usá -lo para cada chamada subsequente no -calculateWordValue:
?
Solução
Este é um trabalho para a palavra -chave estática. Se você fizer isto:
static NSDictionary *pointDictionary = nil
if (pointDictionary==nil) {
NSString *pointPath = [[NSBundle mainBundle] pathForResource:@"pointvalues" ofType:@"plist"];
pointDictionary = [[NSDictionary alloc] initWithContentsOfFile:pointPath];
}
pointDictionary
será persistente para a vida útil do seu aplicativo.
Outra otimização é construir um cache de pontuações usando isso em cada uma de suas palavras:
[dict setObject:[NSNumber numberWithInt:[word calculateWordValue:word]] forKey:word];
Em seguida, use o keysSortedByValueUsingSelector:
Método para extrair sua lista de palavras (observe que o seletor deve ser comparado:, como os objetos comparados são os nsnumbers).
Finalmente, a palavra argumento sobre seu método é redundante. Use eu mesmo:
-(int)calculateWordValue {
...
for (int index = 0; index < [self length]; index++)
{
char currentChar = [self characterAtIndex:index];
...
}
...
}
Outras dicas
Mudar seu sortByPoint:(NSString *) otherString
Método para tomar o dicionário como um parâmetro e passar no seu dicionário pré-criado.
sortByPoint:(NSString *)otherString withDictionary:(NSDictionary *)pointDictionary
EDIT: Não funcionará por causa do uso no STORDArrayWithSelector. Desculpas. Em vez disso, você pode estar melhor criando uma classe de wrapper para o seu dicionário de pontos como um singleton que você obtém uma referência a cada vez que sua função de classificação é executada.
Dentro calculateWordValue
:
NSDictionary *pointDictionary = [[DictWrapper sharedInstance] dictionary];
DictWrapper
tem um nsdictionary como uma propriedade e um método de classe sharedInstance
(Para devolver o Singleton. Você precisa definir esse dicionário e pré-inicializar antes de classificar pela primeira vez.