문제

I've created a custom sorting by creating a new category for the NSString class. Below is my 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

My question is whether I create a point dictionary to determine the point value associated with each character in the alphabet based on a plist. Then in my view controller, I call

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

to sort my table of words by their point values. However, creating a new dictionary each time the -sortByPoint: method is called is extremely inefficient. Is there a way to create the pointDictionary beforehand and use it for each subsequent call in the -calculateWordValue:?

도움이 되었습니까?

해결책

This is a job for the static keyword. If you do this:

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

pointDictionary will be persistent for the lifetime of your app.

One other optimization is to build a cache of scores by using this against each of your words:

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

Then use the keysSortedByValueUsingSelector: method to extract your list of words (note the selector chould be compare:, since the objects being compared are the NSNumbers).

Finally, the word argument on your method is redundant. Use self instead:

-(int)calculateWordValue {
    ...

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

다른 팁

Change your sortByPoint:(NSString *) otherString method to take the dictionary as a parameter, and pass it your pre-created dictionary.

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

EDIT: Won't work because of usage in sortedArrayWithSelector. Apologies. Instead, you may be better off creating a wrapper class for your point dictionary as a singleton which you then obtain a reference to each time your sort function runs.

In calculateWordValue:

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

DictWrapper has an NSDictionary as a property, and a class method sharedInstance (to return the singleton. You have to set that dictionary and pre-initialize it before you do you first sorting.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top