我正在尝试将模糊搜索添加到我使用 Maurice Aubrey http://aspell.net/metaphone/的 double_metaphone 的现有 C++ 实现构建的 iOS 应用程序中。我已将他的主类 double_metaphone.mm 重命名,将其设置为 File Type C++ Source 并构建项目。
但是,EXC_BAD_ACCESS
在调用该DoubleMetaphone
方法后出现错误。我的大多数应用程序都使用 ARC,我在 double_metaphone.mm 类中看到了许多内存管理的东西。也就是说,我最怀疑我是如何试图从该方法中得到答案的。这是 double_metaphone.h 的相关部分(根据从 Objective C 调用 C++ 方法,我将方法声明附在 extern "C" 中)。
void
DoubleMetaphone(const char *str,
char **codes);
以下是 double_metaphone.mm 中方法实现的相关部分
void
DoubleMetaphone(const char *str, char **codes)
{
int length;
metastring *original;
metastring *primary;
metastring *secondary;
int current;
int last;
current = 0;
/* we need the real length and last prior to padding */
length = strlen(str);
last = length - 1;
original = NewMetaString(str);
/* Pad original so we can index beyond end */
MetaphAdd(original, " ");
primary = NewMetaString("");
secondary = NewMetaString("");
primary->free_string_on_destroy = 0;
secondary->free_string_on_destroy = 0;
MakeUpper(original);
/* skip these when at start of word */
if (StringAt(original, 0, 2, "GN", "KN", "PN", "WR", "PS", ""))
current += 1;
/* Initial 'X' is pronounced 'Z' e.g. 'Xavier' */
if (GetAt(original, 0) == 'X')
{
MetaphAdd(primary, "S"); /* 'Z' maps to 'S' */
MetaphAdd(secondary, "S");
current += 1;
}
/* main loop */
while ((primary->length < 4) || (secondary->length < 4))
{
if (current >= length)
break;
switch (GetAt(original, current))
.....
使用 if 语句为每个可能的字符提供一大堆案例,以挑选出不同的模糊编码,并在识别出主要和次要字母时添加字母。
.....
if (primary->length > 4)
SetAt(primary, 4, '\0');
if (secondary->length > 4)
SetAt(secondary, 4, '\0');
*codes = primary->str;
*++codes = secondary->str;
DestroyMetaString(original);
DestroyMetaString(primary);
DestroyMetaString(secondary);
}
最后,这是我调用此方法的代码片段。我导入 double_metaphone.h,然后在一个方法中执行以下操作:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Filtered Word";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Word *word = [self.fetchedResultsController objectAtIndexPath:indexPath];
char *codes;
NSString *wordForMetaphone = [NSString stringWithString:word.spelling];
DoubleMetaphone([wordForMetaphone UTF8String], &codes);
NSLog(@"doubleMetaphone code = %s", codes);
cell.textLabel.text = word.spelling;
return cell;
}
日志消息似乎可以毫无问题地执行,但cell.textLable.text = word.spelling
会触发EXC_BAD_ACCESS
错误。当我单步执行代码时,我也不能 po word.spelling - 我认为 C++ 代码正在炸毁我的指针/内存。但我真的不知道从哪里开始修复它。
注意:最初我刚通过,[word.spelling UTF*String]
但遇到了同样的内存问题。
word.spelling == @"a"
第一次通过代码。当我注释掉我的 4 行代码时,应用程序运行良好。
我也不确定我正在设置 char *codes 并正确引用它,所以我认为这可能会导致问题 - 这不应该是主要和次要的数组吗?
我确实将 DoubleMetaphone 方法的定义从
DoubleMetaphone(char *str, char **codes)
由于“不推荐使用从字符串常量到 'char*' 的转换”警告,请参阅 C++ 不推荐使用从字符串常量到 'char*' 的转换。C++ 类中还有其他一些方法,我还必须切换到 const char* 我希望这不是问题的一部分?
请帮忙!