9

http에서 데이터를 가져 오는 nsurl을 설정했습니다. 장비를 실행할 때 누출 NSFNetwork 개체가 있다고합니다.NSURLConnection 누출?

및 어떻게 연결을 해제합니까 (무효) Button30ed에? 또는 나중에 출시 될 예정입니까?

- (void)ButtonClicked { 
    NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:KmlUrl] 
               cachePolicy:NSURLRequestUseProtocolCachePolicy 
              timeoutInterval:20.0f]; 

    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self]; 
    if (theConnection) { 
     // receivedData is declared as a method instance elsewhere 
     NSMutableData *receivedData = [[NSMutableData data] retain]; 
     [self setKMLdata:receivedData]; 
    } else { 
     // inform the user that the download could not be made 
    } 
} 


- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{ 
    // append the new data to the receivedData 
    // receivedData is declared as a method instance elsewhere 
    [KMLdata appendData:data]; 
    NSLog(@"didReceiveData"); 
} 


- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    // release the connection, and the data object 
    [connection release]; 
    [KMLdata release]; 
} 


- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
{ 
    // release the connection, and the data object 
    [connection release]; 
    // receivedData is declared as a method instance elsewhere 
    [KMLdata release]; 

} 

답변

2

이것은 일반적인 질문이며 [object autorelease]의 마법으로 해결됩니다. 그것은 더 이상 참조 후이 방법으로

NSURLConnection *theConnection = [[[NSURLConnection alloc] initWithRequest:theRequest delegate:self] autorelease]; 

가, 개체가 자동으로 다음 실행 루프의 시작 부분에 "오토 릴리즈 풀"과 dealloc'd에 추가되지 않습니다 다음과 같이 코드에서이 될 것입니다.

편집을하는 데 도움이

희망 :은 또한, 나는 당신이 당신의 receivedData 변수에 -retain 전화를 필요로하는 이유 표시되지 않습니다.

+0

, 그 대리자가 연결이 해제 이전에 출시 된 경우에 실패합니다. 더 좋은 방법은 연결을 인스턴스 변수에 할당하고 필요하지 않을 때 release + nil을하는 것입니다. 객체가 dealloc 될 때 연결 ivar이 여전히 할당되어 있으면 연결을 해제하기 전에 델리게이트를 nil로 설정해야합니다. – rpetrich

+0

@ rfpetrich 나는 귀하의 제안이 더 포괄적이라는 데 동의하지만 그의 질문이 iPhone에서의 메모리 관리에 대한 기본적인 오해를 보여 주었기 때문에 개념적으로 더 쉬운 해결책을주고 싶었습니다. – h4xxr

+0

@rpetrich, 코드 예제를 제공 할 수 있습니까? 나는 여러 가지 방법으로이 문제를 해결하려고 노력했지만 누수가 여전히있다. – Jordan

17

마침내이 문제에 대한 답을 찾았습니다.

위 코드의 오류는 (SDK docs의 거의 정확한 샘플입니다.) 메모리 관리 코드에 없습니다. Autorelease는 하나의 옵션이고, 수동 릴리스는 또 다른 옵션입니다. NSURLConnection 객체를 처리하는 방법에 관계없이 NSURLConnection을 사용하여 누수가 발생합니다.

처음으로 해결책이 있습니다. 이 3 줄의 코드를 직접 connectionDidFinishLoading, didFailWithError 및 다른 곳에서는 NSURLConnection 객체를 릴리스하십시오.

NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil]; 
[NSURLCache setSharedURLCache:sharedCache]; 
[sharedCache release]; 

신용 코드에 대한 http://forums.macrumors.com/showthread.php?t=573253에 mpramodjain합니다.

문제는이 것 같습니다. SDK는 iPhone에서 요청 및 응답을 캐시합니다. NSMutableURLRequest cachePolicy가 캐시에서 응답을로드하지 않도록 설정되어있는 것처럼 보입니다.

바보 같은 점은 기본적으로 많은 양의 데이터를 캐시하는 것입니다. 나는 많은 데이터를 전송 (여러 연결로 분할)하고 메모리 경고를 받기 시작했고, 마침내 내 앱이 죽었다. 우리가 필요로하는 NSURLCache (안있는 NSURLConnection)에

워드 프로세서, 그들은 주 :

NSURLCache이 NSURLRequest가 NSCachedURLResponse 객체에 객체 매핑하여 URL로드 요청에 응답의 캐싱을 구현합니다. 메모리가 인 이고 디스크에 캐시가 입니다.

방법은 캐시 데이터의 영구 저장을 위해 를 사용하는 디스크 경로를 제어하기 아니라 이러한 캐시의 각각의 크기를 조작하기 위해 제공된다.

이 세 줄은 캐시를 완전히 누크하는 효과가 있습니다. 내 앱 (GPS Log)에 추가 한 후 내 #living 개체 수가 계속 안정적으로 유지됩니다.

+0

레코드에 대해 autorelease'd [NSURLConnection connectionWithRequest : delegate : self]로 전환했지만 문제가 될 것이라고 생각하지 않습니다. –

+0

앱이 캐싱을 사용해야하는 다른 NSURL 요청을하면이 솔루션으로 비활성화됩니다. 이 경우에 더 나은 솔루션이 (같은 효과가 있습니다) 캐시 된 응답 대리자를 구현하기 위해 수 있습니다 : '- (NSCachedURLResponse *) 연결 : (있는 NSURLConnection *) 연결 willCacheResponse : (NSCachedURLResponse *) cachedResponse { \t 반환 전무; }' –

+1

실제로 일어나고있는 일에 대해 조금 더 자세히 설명합니다. NSURLCache가 요청에 대한 응답을 캐싱하고 있지만 요청을 키로 사용하고 있습니다. 따라서 응답이 캐시되는 동안 요청을 보류합니다. 0 바이트 캐쉬는 이것을 패배 시키지만, 앱에 의한 모든 요청은 캐싱되지 않습니다. 델리게이트 메서드를 구현하는 것은보다 맞춤화 된 접근 방식입니다. 캐시를 무시하도록 요청의 캐시 정책을 설정하는 것만으로는 충분하지 않습니다. –

5

안녕하세요.이 위임 메서드를 테스트 해 보셨습니까?

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse 
{ 
    return nil; 
} 

캐시를보다 정확하게 관리 할 수 ​​있습니다.

"reset"NSURLCache * sharedCache는 코드의 다른 부분에서 문제를 일으킬 수 있습니까?

1

나는 정적 방법/오토 릴리즈 방식을 사용하고 잘 작동하는 나타납니다

[NSURLConnection connectionWithRequest:theRequest delegate:self]; 

이 방법 당신도 위임 콜백에서 방출에 대해 걱정할 필요가 없습니다. 위의 예에서 alloc'd가 수행 된 후 연결의 보유 횟수가 실제로 2 (1이 아님) 인 것으로 나타났습니다.이 메모리가 "누출"에 대해 생각한 방식을 변경합니다.

@rpetrich 실제로 연결이 해제되기 전에 대리인이 출시되는 것에 대해 걱정할 필요가 없다고 생각합니다. 연결은 대리자를 보유하고 연결 자체는 실제로 일종의 열린 연결 대기열에 보관됩니다. 내 블로그에있는 NSURLConnection 내 실험의 블로그 게시글 작성 시간 : 호출 오토 릴리즈가 작동하지만

"Potential leak of object" with NSURLConnection