Question

J'ai créé un tri personnalisé en créant une nouvelle catégorie pour la classe NSString. Ci-dessous mon 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

Ma question est de savoir si je crée un dictionnaire de points pour déterminer la valeur du point associé à chaque caractère dans l'alphabet basé sur une plist. Ensuite, dans mon contrôleur de vue, j'appelle

NSArray *sorted = [words sortedArrayUsingSelector:@selector(sortByPoint:)];

pour trier ma table de mots par leurs valeurs de point. Cependant, la création d'un nouveau dictionnaire à chaque fois que la méthode est appelée -sortByPoint: est extrêmement inefficace. Est-il possible de créer le pointDictionary au préalable et de l'utiliser pour chaque appel ultérieur dans le -calculateWordValue:?

Était-ce utile?

La solution

Ceci est un emploi pour le mot-clé statique. Si vous faites ceci:

static NSDictionary *pointDictionary = nil
if (pointDictionary==nil) {
    NSString *pointPath = [[NSBundle mainBundle] pathForResource:@"pointvalues" ofType:@"plist"];
    pointDictionary = [[NSDictionary alloc] initWithContentsOfFile:pointPath];
}

pointDictionary sera persistant pour la durée de vie de votre application.

Une autre optimisation est de construire un cache de scores en utilisant ce contre chacun de vos mots:

[dict setObject:[NSNumber numberWithInt:[word calculateWordValue:word]] forKey:word];

Ensuite, utilisez la méthode keysSortedByValueUsingSelector: pour extraire votre liste de mots (notez le sélecteur chould se comparer :, puisque les objets comparés sont les NSNumbers).

Enfin, l'argument de texte sur votre méthode est redondante. Utilisez l'auto à la place:

-(int)calculateWordValue {
    ...

    for (int index = 0; index < [self length]; index++)
    {
        char currentChar = [self characterAtIndex:index];
        ...
    }
   ...
}

Autres conseils

Changez votre méthode de sortByPoint:(NSString *) otherString prendre le dictionnaire comme paramètre, et le transmettre votre dictionnaire pré-créé.

sortByPoint:(NSString *)otherString withDictionary:(NSDictionary *)pointDictionary

EDIT: Ne fonctionne pas en raison de l'utilisation dans sortedArrayWithSelector. Toutes mes excuses. Au lieu de cela, vous pouvez être mieux de créer une classe wrapper pour votre dictionnaire point comme un singleton que vous obtenez alors une référence à chaque fois que votre fonction de tri fonctionne.

En calculateWordValue:

NSDictionary *pointDictionary = [[DictWrapper sharedInstance] dictionary];

DictWrapper a un NSDictionary comme une propriété et une méthode de classe sharedInstance (pour retourner le singleton. Vous devez définir ce dictionnaire et pré-initialiser avant que vous ne vous devez d'abord le tri.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top