Domanda

Ho creato un ordinamento personalizzato creando una nuova categoria per il NSString classe.Di seguito è riportato il mio codice.

@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

La mia domanda è se creo un dizionario dei punti per determinare il valore in punti associato a ciascun carattere dell'alfabeto in base a un plist.Quindi nel mio controller di visualizzazione, chiamo

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

per ordinare la mia tabella di parole in base al loro valore in punti.Tuttavia, creando un nuovo dizionario ogni volta che -sortByPoint: metodo viene chiamato è estremamente inefficiente.Esiste un modo per creare in anticipo pointDictionary e utilizzarlo per ogni chiamata successiva nel file -calculateWordValue:?

È stato utile?

Soluzione

Questo è un lavoro per la parola chiave statica.Se lo fai:

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

pointDictionary sarà persistente per tutta la vita della tua app.

Un'altra ottimizzazione consiste nel creare una cache di punteggi utilizzando questo per ciascuna delle tue parole:

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

Quindi utilizzare il keysSortedByValueUsingSelector: per estrarre l'elenco di parole (nota che il selettore potrebbe essere compare:, poiché gli oggetti da confrontare sono gli NSNumbers).

Infine, la parola argomento sul tuo metodo è ridondante.Usa self invece:

-(int)calculateWordValue {
    ...

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

Altri suggerimenti

Modificare il metodo di sortByPoint:(NSString *) otherString a prendere il dizionario come parametro, e passare il dizionario pre-creato.

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

EDIT: non funzionerà perché di utilizzo in sortedArrayWithSelector. Scuse. Invece, si può essere meglio creare una classe wrapper per il dizionario punto come Singleton che poi ottiene un riferimento ad ogni volta le corse funzione di ordinamento.

In calculateWordValue:

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

DictWrapper ha un NSDictionary come una proprietà, e un metodo di classe sharedInstance (per restituire l'Singleton. È necessario impostare quel dizionario e pre-inizializzarlo prima di fare per la prima volta l'ordinamento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top