iOS 응용 프로그램에 퍼지 검색을 추가하려고합니다. Maurice Aubrey가 double_metaphone을 사용하여 기존 C++ 구현을 사용하여 구현했습니다. http://aspell.net/metaphone/. 나는 그의 메인 클래스 인 double_metaphone.mm을 File Type C++ Source로 설정하고 빌드 할 프로젝트를 얻었다.IOS에서 C++ 클래스를 사용한 후에 잘못된 예외가 발생했습니다.
그러나 DoubleMetaphone
메서드를 호출하면 EXC_BAD_ACCESS
오류가 발생합니다. 내 애플 리케이션의 대부분은 ARC를 사용하고 double_metaphone.mm 클래스에있는 많은 메모리 관리 것들을 볼 수있다. 그것은 내가 그 방법으로 나의 대답을 되 찾으려고 노력하는 방법에 대해 가장 의심 스럽다고 말했다. 다음은 double_metaphone.h의 관련 부분입니다 (메서드 선언을 Calling C++ method from Objective C에 따라 extern "C"로 묶습니다). 여기
void
DoubleMetaphone(const char *str,
char **codes);
는 double_metaphone.mm의 메소드 구현의 relavant 부분입니다
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))
.....
문이 다른 퍼지 코딩을 선택하고에 문자를 추가하는 경우에 가능한 각 문자의 경우 전체 무리 1 차 및 2 차로 구분됩니다.
.....
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를 쓸 수 없다. 둘 중 하나를 적는다 - 나는 C++ 코드가 포인터/메모리를 날려 버리고 있다고 생각하고있다. 그러나 나는 그것을 고치는 것을 어디에서 시작해야할지 정말로 모른다.
참고 : 처음에는 방금 [word.spelling UTF*String]
을 전달했지만 동일한 메모리 문제가 발생했습니다. word.spelling == @"a"
처음으로 코드를 살펴보십시오. 4 줄의 코드를 주석 처리하면 앱이 정상적으로 실행됩니다.
나는 char * 코드를 설정하고 올바르게 참조 했으므로이 문제에 기여할 수 있다고 생각하고 있습니다. 기본 및 보조 배열로해서는 안됩니다.
나는 때문에 경고가 C++ deprecated conversion from string constant to 'char*'를 참조하십시오 " '숯불 *'상수 문자열에서 사용되지 않는 변환"의DoubleMetaphone(char *str, char **codes)
에서 DoubleMetaphone 방법의 정의를 변경했다. C++ 클래스에는 const char *로 전환해야했던 몇 가지 다른 메소드가 있습니다. 문제의 일부가 아니길 바랄뿐입니다.
도와주세요!
"단어"란 무엇입니까? "세포"는 어디에서 얻었습니까? –
Word는 내 모델의 객체입니다. double_metaphone 구현을 테스트하기 위해 단어 표 (사전 앱)를 가져 와서 셀이 그려지는 동안 각 메타 폰 코드를 기록하도록했습니다. 코드 스 니펫은 tableView : cellForRowAtIndexPath에서 가져온 것입니다. 표와 관련된 fetchedResultsController에서 맞춤법을 사용하여 올바른 단어를 가져옵니다. –
그건 아무 말도하지 않습니다. –