0

XML 문서를 구문 분석하는 데 NSXMLParser를 사용합니다. 그것이 편리 시작으로 할당 해제에 출시 될XML 구문 분석기의 메모리 누수

@property (nonatomic, retain) NSMutableString *tempString; 

tempString가 없습니다 :

- (void) parserDidStartDocument:(NSXMLParser *)parser { 

    // Init tempString 
    tempString = [NSMutableString string]; 

}  
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { 

     // save gained data for element "date" 
     if ([elementName isEqualToString:@"date"]) 
      [entryDict setObject:[tempString copy] forKey:kXMLDictDateKey]; 

     [tempString setString:@""]; 
    } 


    // 
    // Character Handling 
    // 
    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 
     [tempString appendString:[[XMLParser alloc] stripUnwantedStringChars:string]]; //Just strips tabs and linebreaks and the returns the string 
    } 

tempString는 다음과 같은 속성 인스턴스 변수입니다 : 내가 (다른 사람의 사이에서) 다음과 같은 기능을 가지고 있습니다 메소드가 자동으로 자동 해제 풀에 할당됩니다. 나는 또한 같은 결과를 가지고 alloc, init 접근법으로 다음을 시도했다. 그래서 내가 한 일이 여기에 있습니다 :

1) 악기로 프로젝트를 실행하고, 시작 직후에 누출을 찾게하십시오. 아무 것도 없습니다. 2.) XML 파서를 한 번 실행하고 누출 여부를 확인하십시오. 아무도 없다. 3.) XML 파서를 다시 실행하십시오. 갑자기 [entryDict setObject:[tempString copy] forKey:kXMLDictDateKey];이있는 행이 유출되었습니다.

나는 몇 시간 동안 이러한 메모리 누출을 조사해 왔지만, 무엇을 잊었나요? 더 많은 코드가 필요하면 저에게 알려주십시오. 제 문제는이 줄의 어딘가에 있다고 생각합니다.

ps. 내 검사는 파서 (델리게이트) 호출간에 "dealloc"메서드가 호출된다는 것을 보여 주므로 파서가 실제로 한 번만 두 번로드되는 것 같습니다.

답변

3

귀하의 전화.

대신이 작업을 수행해야합니다

self.tempString = [NSMutableString string]; 

그렇지 않으면 당신은 단지 오토 릴리즈 객체에 직접 바르를 설정한다.

어딘가에 누수가있을뿐만 아니라 위의 코드는 어느 시점에서 재미있는 충돌을 일으 킵니다.

+0

고마워, 이것이 내가 놓친 것이었다. 이제는 매력처럼 작동합니다. – Robin

0

우선 autoreleased 변경 가능한 문자열은 parserDidStartDocument에서 반환 된 직후에 릴리스되어야하므로 실제로 충돌이 발생해야한다고 생각합니다. 그것은 일종의 관심사는 아니며, 재산이 보유되지 않았을 때 재산이 보유되었다고 주장함으로써 재산 정의에 거짓말을하고 있습니다.

그러나 누출은 문자열의 복사본이 유출되었다는 것을 나타냅니다. 누수는 누출 된 개체가있는 곳을 보여 주지만 누출의 원인은 아닙니다. 누수의 원인은 나중에 문자열을 적절하게 해제해야하는 코드 줄입니다. 누수가 존재하지 않는 코드를 가리킬 수 없으므로, 누출이 올바르게 해제되지 않은 오브젝트를 만들었 음을 보여줄 수 있습니다.

[entryDict setObject:[[tempString copy] autorelease] forKey:kXMLDictDateKey]; 

이 복사는 단지 ALLOC/초기화 등의 사본을 (유지하기 때문에 : 당신이 말을 할 수 있도록 -이 경우

, 내가 무엇을 누락하는 배열 오토 릴리즈 된 개체를 보유해야한다고 생각합니다 할 것이다).

tempString = [NSMutableString string]; 

가 실제로 재산 (래퍼)와 retain를 호출하지 않습니다에

+0

빠른 답변 주셔서 감사합니다. autorelease에 tempString을 첨부하는 연습은 Apple의 샘플 코드에서 "XML Performance"프로젝트에 복사되었습니다. 당신이 제안한 자동 회수 기능을 추가 했는데도 여전히 누수가 있습니다. tempString이 제대로 할당 해제되지 않는 이유는 나에게 수수께끼이다 (나는 이것이 문제라고 생각한다). 나는 또한 "entryDict"가 공개되는지 확인했다. 그래서 문제는 실제로 tempString 내에 있다고 생각한다. 누출의 원인이 될 수있는 다른 생각이 있습니까? 노력해 주셔서 감사합니다. – Robin

+0

entryDict는 무엇이 출시됩니까? 그게 풀려 나지 않는다면 그 안에있는 요소들이 누설되고 있다고 말할 수있는 곳을 볼 수 있습니다. –

1

코드의 다른 버그는 다음과 같습니다

[tempString appendString:[[XMLParser alloc] 
    stripUnwantedStringChars:string]]; 

이 새로운 XMLParser를 할당하고 그것을 제거하지 없구요.

+0

예, 맞습니다. XMLParser가 싱글 톤이라는 설명을 쓰는 것을 잊었습니다. 따라서 XMLParser의 새 인스턴스를 만들지 않고 이전 인스턴스 만 반환합니다. – Robin

+0

더 좋은 방법은 애플 스타일을 따르고'sharedInstance' 클래스 메소드를 사용하는 것입니다. 싱글 톤을 만들기 위해'alloc'을 쓰는 것은 악하고 정말로 나쁜 스타일이다. –

1

나는 tempString에 대한 할당에서 무엇을했는지 알아 내려고하고 있습니다. 당신이이 일을하는 경우 :

self.tempString = [NSMutableString string]; 

을 당신은이의 dealloc에 ​​tempString를 해제해야합니까 . 자동 릴리즈되고 있지만, 설정자는 그것을 유지하고 있습니다.