문제

업데이트: 코드를 편집했지만 문제는 지속됩니다 ...

안녕하세요 여러분,
이것은 나의 첫 번째 게시물입니다 - 나는이 장소가 많은 질문을 해결하기위한 훌륭한 ressource를 발견했습니다. 일반적으로 나는 스스로 모든 것을 고치기 위해 최선을 다하지만 이번에는 실제로 무엇이 잘못되는지 전혀 모른다. 그래서 누군가 나를 도울 수 있기를 바랍니다.
TouchXML을 사용하여 몇 개의 XML 파일을 구문 분석하는 iPhone 앱을 구축하고 있습니다. 클래스 XMLPARSER가 있는데 결과를 다운로드하고 구문 분석해야합니다. XMLPARSER의 동일한 인스턴스로 XML 파일을 두 번 이상 구문 분석 할 때 메모리 누출이 발생합니다. 다음은 구문 분석 스 니펫 중 하나입니다 (관련 부분 만).

for(int counter = 0; counter < [item childCount]; counter++) {  
        CXMLNode *child = [item childAtIndex:counter];
        if([[child name] isEqualToString:@"PRODUCT"]) 
        {
            NSMutableDictionary *product = [[NSMutableDictionary alloc] init];
            for(int j = 0; j < [child childCount]; j++) {
                CXMLNode *grandchild = [child childAtIndex:j];
                if([[grandchild stringValue] length] > 1) {
                    NSString *trimmedString = [[grandchild stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
                    [product setObject:trimmedString forKey:[grandchild name]];
                }
            }

            // Add product to current category array
            switch (categoryId) {
                case 0:
                    [self.mobil addObject: product];
                    break;
                case 1:
                    [self.allgemein addObject: product];
                    break;
                case 2:
                    [self.besitzeIch addObject: product];
                    break;
                case 3:
                    [self.willIch addObject: product];
                    break;
                default:
                    break;
            }
            [product release];
        }

    }  

처음으로, 나는 XML No Leak가 악기에 표시되는 것을 구문 분석합니다. 다음에 그렇게 할 때, 나는 많은 누출 (nscfstring / nscfdictionary)을 얻었습니다.
악기가 나를 가리킨다 이 부분은 cxmlnode.m 내부입니다, 유출 된 물체를 파헤칠 때 :

theStringValue = [NSString stringWithUTF8String:(const char *)theXMLString];
if ( _node->type != CXMLTextKind )
   xmlFree(theXMLString);
}

return(theStringValue);  

나는 정말로 오랜 시간을 보냈고 이것을 고치기 위해 여러 가지 접근법을 시도했지만 지금까지는 아무 소용이 없어도 필수적인 것을 놓치고 있습니까?

도움을 주셔서 감사합니다. 감사합니다!

도움이 되었습니까?

해결책

문제는이 라인에있을 가능성이 높습니다.

[self.mobil addObject:[product copy]];

사본을 요청함으로써 product 1의 유지 카운트로 새로운 nsmutabledictionary 인스턴스를 만들고 있습니다. mobil 그러나 인스턴스는 보낼 때 사본의 유지 카운트를 증가시킵니다. addObject: 메시지, 그래서 사본의 유지 카운트는 이제 2입니다. 일반적으로 말하면, 객체는 자체 객체 메모리를 처리 할 책임이 있습니다. setFoo: 또는 addObject:, 당신은 autoreLed 또는 통화 직후에 그것을 릴리스 할 계획이더라도 객체를 직접 전달할 수 있습니다. 그것을 붙잡아 야 할 경우 통과하는 객체를 유지하는 것은 수신자의 책임입니다.

사본을 변수에 할당하지 않았기 때문에 더 이상 관심이 없으므로 이제 사본 유지 카운트를 줄이는 데 사용할 수있는 포인터가 없습니다. mobil 어느 시점에서 제품 사본을 출시하면 사본은 0의 유지에 도달하지 않습니다. [product release] For Loop의 끝에있는 문장은 원본을 릴리스합니다. product 객체, 당신이 만든 사본이 아닙니다.

대신, 다음을 시도하고 악기가 더 행복한 지 확인하십시오.

[self.mobil addObject:product];

다른 팁

간단히 말해서, 당신이 사용할 때마다 copy, 당신은 또한 사용해야합니다 release/autorelease 어딘가에.

그리고이 경우 더 쉬운 대답은 사용하지 않는 것입니다. copy 처음에는 원래 버전으로 아무것도하지 않기 때문에 product 복사 한 후.

나는 문제를 직접 고쳤다. 그것은 어리석은 일 이었지만 누군가가 같은 것을 발견했을 수도 있습니다. 그래서 나는 그것을 여기에 게시 할 것입니다.

1) 나는 이와 같은 인스턴스 변수로서 변수 배열을 설정했다.

@interface XMLParser : NSObject {

// ...  
NSMutableArray *mobil;  
// ...  
}   
@property(nonatomic, retain) NSMutableArray *mobil;  
@end  

내부의 새로운 데이터를 복원하고 싶을 때마다 다음을 수행했습니다.
self.mobil = nil;
내가하고 싶었던 일이 아니 었으므로 이것은 더 나은 접근법입니다.
self.mobil removeallobjects];

2) Dealloc 방법은 누출을 고정하기 위해 이와 같아야합니다 (Mobil은 속성으로 정의되기 때문에) :
-(void) dealloc {
Mobil Release];
self.mobil = nil;
}

WHEW, 그것은 알아내는 많은 일이었습니다 - 그것은 다른 시간을 절약하기를 바랍니다 :-)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top