Objective-C 类别问题

发布于 2024-10-02 14:59:31 字数 1521 浏览 5 评论 0原文

我通过为 NSString 类创建一个新类别来创建自定义排序。下面是我的代码。

@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

我的问题是我是否创建一个点字典来根据 plist 确定与字母表中每个字符关联的点值。然后在我的视图控制器中,我调用

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

按点值对单词表进行排序。但是,每次调用 -sortByPoint: 方法时创建一个新字典的效率极低。有没有办法预先创建 pointDictionary 并将其用于 -calculateWordValue: 中的每个后续调用?

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:?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

毁虫ゝ 2024-10-09 14:59:31

这是 static 关键字的工作。如果您这样做:

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

pointDictionary 将在您的应用程序的生命周期内保持不变。

另一种优化是通过针对每个单词使用此方法来构建分数缓存:

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

然后使用 keysSortedByValueUsingSelector: 方法提取单词列表(请注意,选择器应该是 Compare:,因为对象被比较的是 NSNumbers)。

最后,你的方法中的参数这个词是多余的。使用 self 代替:

-(int)calculateWordValue {
    ...

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

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];
        ...
    }
   ...
}
浅忆 2024-10-09 14:59:31

更改您的 sortByPoint:(NSString *) otherString 方法以将字典作为参数,并将其传递给您预先创建的字典。

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

编辑:由于在sortedArrayWithSelector中使用而无法工作。抱歉。相反,您可能最好为点字典创建一个包装类作为单例,然后您每次运行排序函数时都会获得对它的引用。

calculateWordValue 中:

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

DictWrapper 有一个 NSDictionary 作为属性,还有一个类方法 sharedInstance (用于返回单例。您必须设置该字典并在第一次排序之前对其进行预初始化。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文