2009-10-08 3 views
0

안녕하세요. 모두 메모리 누수 문제가 발생했습니다. 내 내가 그들에게 할당 해제 때 카운트 = 0을 유지하지만 여전히 나는 다음과 같은 코드에서 누출을 신고하고 모든 떨어져 : 그렇게하지 않으면, 그래서 피어 선택기를 취소에메모리 누출 문제가 발생했습니다.

- (GKSession *) peerPickerController:(GKPeerPickerController *)picker sessionForConnectionType:(GKPeerPickerConnectionType)type { 
inSession = [[GKSession alloc] initWithSessionID:gameSessionID displayName:nil sessionMode:GKSessionModePeer]; 
printf("insession alloc on Start: %i\n", [inSession retainCount]); 
return inSession; 

}

연결할 사람을 찾으면이 코드를 실행하여 피어 선택 도구와 관련된 모든 것을 제거합니다.

- (void)peerPickerControllerDidCancel:(GKPeerPickerController *)picker { 
picker.delegate = nil; 
mpicker.delegate = nil; 
inSession.delegate = nil; 
gameSession.delegate = nil; 

if(inSession != nil) { 

    [self invalidateSession:inSession]; 
    [inSession release]; 
    inSession = nil; 

} 

[picker release]; 

picker = nil; 
mpicker = nil; 



[inSession release]; 


if(self.gameSession != nil) { 
    [self invalidateSession:self.gameSession]; 
    [self.gameSession release]; 
    self.gameSession = nil; 
} 

[self.gameSession release]; 
self.gameLabel.hidden = NO; 
self.gameState = pongStateStartGame; 


[gameSession release]; 
[inSession release]; 

[inSession dealloc]; 
[gameSession dealloc]; 



[mpicker dealloc]; 

}

어딘가에는, 코드가 유출되고 난 내 인생에 대한 알아낼 수 없습니다. 어떤 도움이라도 굉장히 감사 할 것입니다.

+0

나는이 코드가 전혀 작동하지 않는다는 것에 놀랍니다 ... 마지막 세션에서 3 회의 세션을 해제 할 가능성이 있습니다. NSObject의 release 메소드는 보유 카운트가 0이 되 자마자 취소됩니다. 대리자는 소유 참조 (+1)가있는 GKSession을 반환합니다. 내 생각 엔이 델리게이트로부터 GKSession을 가져 오는 클래스가 이전에 생성 된 GKSession을 공개하지 않는다는 것입니다. 따라서 peerPickerController : sessionForConnectionType :이 다시 호출되면 다른 GKSession을 반환하고 이전 GKSession의 누락 된 메모리 (누출 된 메모리)를 잃게됩니다. – pxl

답변

3

누설을 찾으려면 Instruments을 사용하십시오.

문제는 아직 코코아의 memory management을 이해하지 못했다는 것입니다.

[inSession dealloc]; 
[gameSession dealloc]; 
[mpicker dealloc]; 

당신은 -dealloc 직접 전화를하지 않아도한다. NSObject은 참조 횟수가 0에 도달하면이를 호출합니다.

메모리를 관리하는 올바른 방법을 배우십시오.

2

Xcode 3.2의 빌드 및 분석 (빌드 메뉴 아래)을 실행하는 것을 고려하십시오. 이는 참조 계산 문제를 찾는 데 매우 유용 할 수 있습니다.

만약 도움이되지 않는다면, 계측기 (실행 -> 성능 도구로 실행 -> 누출)에서 누수 도구를 실행하십시오.

0

변수 포인터를 nil로 설정 한 후에 다시 해제하려고하면 아무 효과가 없습니다. 아무 것도하지 않습니다. 또한 dealloc을 호출하지 마십시오. 기술적으로 불법 당신의

- (GKSession *) peerPickerController:(GKPeerPickerController *)picker sessionForConnectionType:(GKPeerPickerConnectionType)type

방법은 누출의이 종류로 이어질 수있는 스타일의 scrappyness을 나타냅니다 동안. 그것은 새로운 GKSession을 생성하고 그것을 인스턴스 변수로 설정하고 그것에 대한 참조를 반환합니다. 인수 중 하나를 사용하지 않습니다. 인스턴스 변수를 만들거나 자동으로 릴리스하여 반환하십시오. 이 메소드를 호출하는 코드는 어디에 있습니까? 호출자가 반환 된 값을 유지하고 있습니까?

+0

은 계측기를 사용하고 있으며 계측기 내에 있습니다. 빌드 및 분석을 사용했지만 아무 것도 나타나지 않습니다. 아무런 힌트가 없습니다. 또한 모든 보유 수는 0이되었으므로 dealloc을 입력하면됩니다. 기기가 다른 누출을 검사 할 때 여전히 오류가 있습니다. –

+0

당신은 여전히 ​​그것을 정돈해야합니다. (GKSession *) sessionForConnectionType : (GKPeerPickerConnectionType) type { \t return [[GKSession alloc] initWithSessionID : gameSessionID displayName : nil] autorelease];를 유지하기 위해 inSession 속성을 설정하십시오. } // 할당 할 self.inSession = [whichObject? sessionForConnectionType : type]; - - // 릴리스 할 self.inSession = nil; 좀비가 켜져 있습니까? –

+0

나는 autorelease로 세션을 반환 한 apple의 원본 코드를 가지고 있었지만 결코 사용되지 않았고 피어의 선택자가 취소 될 때 릴리스되지 않았습니다. 모든 문제가 시작되었습니다. –

0

코드의 두 번째 비트에 [inSession release]을 두 번 넣은 다음 THEN dealloc을 입력하십시오.

죄송합니다.하지만 약 200 가지 유형의 오류가 있습니다.

전화하지 않음 dealloc 시스템에서 자동으로 수행합니다.

같은 방법으로 같은 개체에 대해 release을 두 번 호출하지 마십시오. 첫 번째 호출 후에도 개체가 있는지 여부를 알 수 없습니다. 나는 당신이 누출이 많은 예외를 얻지 않고 놀랍다.

보관 및 사용에 대한 간단한 설명은 question을 참조하십시오.

자세한 내용은 (그리고 매우 가치있는) 주제에 대한 코코아 문서화를 읽어보십시오.

+0

나는 유지와 석방의 배경에있는 원칙을 잘 알고 있습니다. 그래서 지금 당황스럽고 필사적입니다. 카운트가 0이면 내가 사용하는 모든 것에 대해 inSession으로 누수를 찾는 계기가되는 이유는 무엇입니까? 이상, 사용자가 수동으로 변수를 릴리스 할 수 없었던 원래 사과 코드. –

0

[x retainCount]를 사용하여 메모리 문제를 식별하는 데 "도움을"주시면됩니다. 여러 번 배웠고 시도한 것처럼 올바른 상황을 반영하지 못할 수 있습니다. 따라서이 값에 의존하지 마십시오.이 값을 사용하지 마십시오. 아마도 혼동을 일으킬 것입니다.

둘째, Apple 코드 (이 예제에서는 물론)를 사용하고 나서 "파란색으로"내 코드에서 문제를 일으키는 것은 항상 발생합니다 (LEAKS 악기에 나타남) - 물론 그것을 학대하는 것. 때때로 나는 몇 시간 이상을 보내고 이상한 행동에 이상한 이유를 찾습니다. 예를 들어 UINavigationControllerDelegate를 프로토콜로 추가하면 다른 코드 줄을 변경하지 않고 코드가 갑자기 누출 될 수 있습니다!