ここ SO で得た多くの支援のおかげで、合計約 50,000 の単語のリストに対して、部分アナグラムの約 15,000 の 8 文字の単語のリストをチェックするアルゴリズムを取得しました (したがって、合計で1 億 800 万回の反復)。このメソッドは、比較ごとに 1 回呼び出します (つまり、7 億 5000 万回)。次のエラーが発生します。常に、1,350 までの 119 回目の反復の途中にあるはずです。
AnagramFINAL(2960,0xac8c7a28) malloc: *** mmap(size=2097152) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
メモリの問題を、膨大な数の割り当てられた CFString (不変) に絞り込みました。問題を解決するために何ができるか考えていますか? 私は ARC と を使用して@autoreleasepool
いますが、他に何ができるかわかりません。リリースすべきときに何かがリリースされていないようです。
AnagramDetector.h
#import <Foundation/Foundation.h>
@interface AnagramDetector : NSObject {
NSDictionary *allEightLetterWords;
NSDictionary *allWords;
NSFileManager *fileManager;
NSArray *paths;
NSString *documentsDirectory;
NSString *filePath;
}
- (BOOL) does: (NSString *) longWord contain: (NSString *) shortWord;
- (NSDictionary *) setupAllWordList;
- (NSDictionary *) setupEightLetterWordList;
- (void) saveDictionary: (NSMutableDictionary *)currentArray;
@end
AnagramDetector.m
@implementation AnagramDetector
- (id) init {
self = [super init];
if (self) {
fileManager = [NSFileManager defaultManager];
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDirectory = [paths objectAtIndex:0];
}
return self;
}
- (BOOL) does: (NSString *) longWord contain: (NSString *) shortWord {
@autoreleasepool {
NSMutableString *longerWord = [longWord mutableCopy];
for (int i = 0; i < [shortWord length]; i++) {
NSString *letter = [shortWord substringWithRange: NSMakeRange(i, 1)];
NSRange letterRange = [longerWord rangeOfString: letter];
if (letterRange.location != NSNotFound) {
[longerWord deleteCharactersInRange: letterRange];
} else {
return NO;
}
}
return YES;
}
}
- (NSDictionary *) setupAllWordList {
@autoreleasepool {
NSString *fileWithAllWords = [[NSBundle mainBundle] pathForResource:@"AllDefinedWords" ofType:@"plist"];
allWords = [[NSDictionary alloc] initWithContentsOfFile: fileWithAllWords];
NSLog(@"Total number of words: %d.", [allWords count]);
}
return allWords;
}
- (NSDictionary *) setupEightLetterWordList {
@autoreleasepool {
NSString *fileWithEightWords = [[NSBundle mainBundle] pathForResource:@"AllDefinedEights" ofType:@"plist"];
allEightLetterWords = [[NSDictionary alloc] initWithContentsOfFile: fileWithEightWords];
NSLog(@"Total number of words: %d.", [allEightLetterWords count]);
}
return allEightLetterWords;
}
- (void) saveDictionary: (NSMutableDictionary *)currentArray {
@autoreleasepool {
filePath = [documentsDirectory stringByAppendingPathComponent: @"A.plist"];
[fileManager createFileAtPath:filePath contents: nil attributes: nil];
[currentArray writeToFile: filePath atomically:YES];
[currentArray removeAllObjects];
}
}
@end
起動時に実行されるコード (VC がないため、今のところ AppDelegate 内):
@autoreleasepool {
AnagramDetector *detector = [[AnagramDetector alloc] init];
NSDictionary *allWords = [[NSDictionary alloc] initWithDictionary:[detector setupAllWordList]];
NSDictionary *eightWords = [[NSDictionary alloc] initWithDictionary:[detector setupEightLetterWordList]];
int remaining = [eightWords count];
for (NSString *currentEightWord in eightWords) {
if (remaining % 10 == 0) NSLog(@"%d ::: REMAINING :::", remaining);
for (NSString *currentAllWord in allWords) {
if ([detector does: [eightWords objectForKey: currentEightWord] contain: [allWords objectForKey: currentAllWord]]) {
// NSLog(@"%@ ::: CONTAINS ::: %@", [eightWords objectForKey: currentEightWord], [allWords objectForKey: currentAllWord]);
}
}
remaining--;
}
}