2010-04-21 1 views
2

다음은 NSXMLParser를 사용하여 문자열에서 모든 HTML 태그를 제거하는 데 사용하는 MREntitiesConverter 객체의 @interface입니다. 나는 내 응용 프로그램을 충돌하고있는 할당 해제의 방법이 아니라 내가 확실히 분명히 메모리를 유출하고 방출하지 않고 xmlParser을 떼면내 응용 프로그램을 중단하지 않고이 NSXMLParser를 어떻게 해제 할 수 있습니까?

@implementation MREntitiesConverter 
@synthesize resultString; 
- (id)init 
{ 
    if([super init]) { 
     self.resultString = [NSMutableString string]; 
    } 
    return self; 
} 

- (NSString*)convertEntitiesInString:(NSString*)s { 
    xmlStr = [NSString stringWithFormat:@"<data>%@</data>", s]; 
    data = [xmlStr dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; 
    xmlParser = [[NSXMLParser alloc] initWithData:data]; 

    [xmlParser setDelegate:self]; 
    [xmlParser parse]; 

    return [resultString autorelease]; 
} 

- (void)dealloc { 
    [data release]; 
    //I want to release xmlParser here but it crashes the app 
    [super dealloc]; 
} 

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)s { 
    [self.resultString appendString:s]; 
} 
@end 

:

@interface MREntitiesConverter : NSObject { 
    NSMutableString* resultString; 
    NSString* xmlStr; 
    NSData *data; 
    NSXMLParser* xmlParser; 
} 
@property (nonatomic, retain) NSMutableString* resultString; 
- (NSString*)convertEntitiesInString:(NSString*)s; 
@end 

는 그리고 이것은 구현입니다.

저는이 악기를 처음 사용하고이 앱을 최적화하려고 노력하고 있습니다. 이 특정 문제에 대해 도움을 줄 수 있다면 내 앱의 다른 메모리 문제를 해결하는 데 도움이 될 것입니다. 좌절 기대에

너의 :) Oisin

+0

오늘 실제로 같은 문제가있었습니다. 이것에 대한 답을보기를 좋아할 것입니다. –

답변

3

클래스와 NSXMLParser가 모두 데이터를 방출하고있어 현재 충돌이 발생합니다. 유일한 멤버는 resultString이어야합니다. convertEntitiesInString : init이 아닌 resultString을 초기화해야합니다. 동일한 인스턴스가 두 번 이상 사용될 수 있습니다. convert에서 self.resultString 또는 [[resultString retain] autorelease]를 반환해야합니다. 왜냐하면 현재 수행중인 작업은 resultString을 dealloc에서 해제해야 할 때 나중에 두 번 릴리스 될 것이기 때문입니다. 메소드 호출 인 self.resultString 대신에 파서 : foundCharacters :에서 resultString을 직접 사용해야합니다.

+0

제안 해 주셔서 감사합니다 ... 나를 위해 메모리 관리를 명확히하는 데 도움이되었습니다. 나는 코드의 최신 버전으로 내 자신의 "답변"을 게시 할 예정입니다 – prendio2

2

내가 xmlParser가 표시되지는 convertEntitiesInString:의 외부에서 사용된다. 을 인스턴스 변수가 아닌 해당 메소드에 대해 로컬로 만들 수 있고 그 메소드에서 완료 한 후에는 return [resultString autorelease] 행 앞에 놓을 수 있습니다.

+0

덕분에, 너무 많은 인스턴스 변수가 발생했습니다 ... 이것은 충돌을 수정하지 않았지만 코드를 더 잘 만들었습니다. – prendio2

2

[xmlParser release]가 (가) 응용 프로그램을 dealloc에서 크래킹하고 있습니까? dealloc에 ​​[data release]가 있는데 메모리를 할당하기 위해 alloc을 사용한 구문을 볼 수 없습니다. 다른 두 의견은 (당신이 release에 메모리 누수가되는 방법 당신 alloc 그것에서 파서를 잊고있어) 올바른 동안

+0

예, 맞습니다 ... xmlParser에 전달할 데이터 인스턴스를 만들었지 만 그것에 dealloc 호출 * 및 * xmlParser에 나는 응용 프로그램을 파괴했다. 감사. – prendio2

0

, 나는 당신이에 대한 delegateMREntitiesConverter 클래스를 설정하기 때문에 특별히 충돌 내기 파서.

+0

MREntitiesConverter는 문자열을 처리하고 최종 resultString을 생성하는 대리자 여야합니다. – prendio2

+0

일부 클래스에는 대리자가 전달되기 전에 할당이 취소되는 문제가 있습니다. 이전 버전의 SDK에서는 UIWebView가 이러한 문제를 겪고 있습니다. –

0

나는 그것이 resultString이라고 믿는다. 이것은 충돌을 일으킨다. 이것은 NSMutableString이며 이것에 대한 메모리를 할당하지 않았습니다. 또한 return [resultString autorelease] 전에 convertEntitiesInString에서 xmlParser를 해제하십시오. 여기에 몇 가지 정말 도움이 sugestions을 바탕으로

+0

resultString은 @property로 설정되어 있으며 합성되어 있습니다. 그리고 self.resultString = [NSMutableString string]을 쓸 때 메모리가 할당되어 있다는 것을 이해합니다. - 또는 오해 받아 들여야합니다. 어떤 것? – prendio2

0

,이 메모리 누수가 표시되지 않습니다 내 코드의 최신 버전입니다 :

@interface MREntitiesConverter : NSObject { 
    NSMutableString* resultString; 
} 
@property (nonatomic, retain) NSMutableString* resultString; 
- (NSString*)convertEntitiesInString:(NSString*)s; 
@end 


@implementation MREntitiesConverter 
@synthesize resultString; 

- (NSString*)convertEntitiesInString:(NSString*)s { 
    self.resultString = [NSMutableString string]; 

    NSString* xmlStr = [NSString stringWithFormat:@"<d>%@</d>", s]; 
    NSData *data = [xmlStr dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; 
    NSXMLParser* xmlParse = [[NSXMLParser alloc] initWithData:data]; 

    [xmlParse setDelegate:self]; 
    [xmlParse parse]; 
    [xmlParse release]; 

    return [self.resultString autorelease]; 
} 

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)s { 
    [resultString appendString:s]; 
} 
@end 

유일한 기이는 그 난 그냥 이전 resultStringretainCount을 추적하는 경우 그것을 반환하는 데 나는 1이 될 것이라고 예상했던 2의 수를 얻습니다. 왜 그런가?