2010-03-23 3 views
1

나는 사과 코드에 대한 부동의 코드와 유사한 라인을 보았다 :메모리 누수가 사용 (무효) ALLOC

(void)[[URLRequest alloc] initializeRequestWithValues:postBody url:verifySession httpHeader:nil delegate:self]; 

된 URLRequest 내 자신의 사용자 정의 클래스입니다. 나는이 글을 쓰지 않았고 나는 단지 애플의 예에서 그것을 얻은 사람을 잡았다 고 생각한다. 나에게 이것은 누출되어야하고 나는 그것을 테스트 할 때 16 바이트 누설을 확신한다. 그럴 거니? Apple의 코드에서 가져온 것이지만 확실하지 않은 경우이를 수정하는 방법을 알고 있습니다.

편집 : 문제는 위의 코드가 아니라 SDK에서 발생했습니다. 자세한 내용은 아래의 답변을 참조하십시오.

+0

'-initializeSomething'으로 시작하는 메소드로 코드를 사용하겠습니까/사용하지 마십시오 :'-initSomething' 메소드의 이름을 지정하기에 충분한 Objective-C를 모르는 사람은 누출을 정확히 피하지 않을 것입니다 : 그 동안 가혹한 것처럼 들릴지 모르겠지만 실제로는 툴 세트에 익숙하지 않은 단순한 오류가있을 수 있습니다. –

+1

:/당신은 요점을 가지고 있지만 그 선택은 아니지? 그는 단어를 줄이기 위해 열렬한 증오를 가질 수도 있습니다. 그의 코드의 나머지는 누설되지 않습니다 – Rudiger

+0

Rudiger : 적절한 명명 규칙에 따라/항상/좋은 생각입니다. –

답변

3

생각해 본 후에 테스트를 추가하고 iOS4가 출시 된 이후로 변경 될 수 있습니다.

위의 코드는 누출되지 않으며 코드 반복 횟수를 200 회 수행 한 후에도 앱의 메모리 사용 공간이 정상으로 돌아갑니다. 누출은 iOS3에서 발생했지만 매우 작았습니다. iOS4에서는 시뮬레이터와 장치에서 완전히 사라졌습니다.

일부 사용자는이 코드를 구현해야하는 이유가 궁금 할 수 있지만 동시에 실행되는 코드 전체에서 다양한 NSURLConnection을 처리 할 때 효과적입니다.

2

이 코드가 달성해야하는 것이 무엇인지 확실하지 않습니다. 초기화 방법에 대해 모든 규칙을 위반하는 것처럼 보입니다. 초기화 메소드에서 void 포인터를 반환하는 것은 무엇입니까? 초기화 메소드의 핵심은 객체를 반환하는 것입니다. 애플의 코드 예제에서 이것을 어디에서 보았습니까?

그렇다고해서 내가 누출되는 이유를 모르겠다. 객체를 반환하지 않으므로 메소드 외부로 누출 될 수 없습니다. 내부적으로 누수가있을 수 있습니다.

편집 :

It basically does an NSURLConnection. Because we are submitting a lot of forms with a lot of different values we put it in an external class. All the delegate methods like didFailWithError: are in NSURLRequest and connectionDidFinishLoading just passes the data to its delegate. So it doesn't really need to return anything as it is done through a delegate method.

그래, 당신은이를 재 설계 할 필요가있다. 현재이 방법은 재발을 기다리는 재앙 일뿐입니다. 다른 것이 없다면,이 코드를 보는 다른 모든 사람들은 당신이하는 일에 대해 완전히 혼란 스러울 것입니다.

생성 된 개체를 유지할 필요가없는 경우 할당을 이동하고 메서드 내에서 완전히 정리하십시오. 메서드 이름 접두사를 "초기화"에서 "설정", "구성", "획득"등으로 변경하여 이름이 생성 및 반환하고 객체한다는 것을 암시하지 않도록합니다.

특정 클래스의 원 샷 인스턴스가 필요한 경우 Michael Aaron Safyan과 같은 클래스 메소드를 사용하십시오 (다시 이름으로 초기화하지 않음). 클래스 메소드는 인스턴스를 내부적으로 초기화하고 필요한 작업을 수행하며 데이터를 어디서나 가져온 다음 인스턴스를 dealloc하십시오.

그런 식으로 누수에 대해 걱정할 필요가 없으며 코드를 읽을 수있는 모든 사람들 (코드 달기 몇 개월 포함)은 코드의 내용을 즉시 이해합니다.

+0

기본적으로 NSURLConnection을 수행합니다. 우리는 많은 다른 값을 가진 많은 형식을 제출하기 때문에 외부 클래스에 넣습니다. didFailWithError :와 같은 모든 델리게이트 메소드는 NSURLRequest에 있고 connectionDidFinishLoading은 데이터를 델리게이트로 전달합니다. 따라서 델리게이트 메서드를 통해 수행되는 것처럼 실제로 아무 것도 반환하지 않아도됩니다. – Rudiger

+0

예. 알아 내야 할 나이가 들었는데 그 사람이 나에게 애플 데모 코드를 보여 주었다. 나는 모든 것을 고칠 수 있고 다시 시작할지도 모른다라고 생각해라. – Rudiger

2

예. 이것은 쉽게 오토 릴리즈를 추가하여 고정 할 수있는 누수입니다 :

 
[[[URLRequest alloc] initializeRequestWithValues:postBody url:verifySession httpHeader:nil delegate:self] autorelease]; 

아마도 더 나은 수정이 수행하는 클래스 함수를 작성하는 것입니다 :

그런 다음
 
@interface URLRequest 
{ 
    // ... 
} 
// ... 
+ (void) requestWithValues:/* ... */ 
// ... 
@end 

간단히 사용할 수를 [ URLRequest requestWithValues ​​:/* ... * /]를 호출하지 않고 alloc을 호출합니다.

+0

URLRequest의 NSURLConnection이 실행 루프 이후에 응답 할 수 있기 때문에 실제로 autorelease를 호출 할 수 없습니다. 나는 그것을 시도하고 그것은 충돌합니다. 더 나은 소리가 들리지만 다른 문제를 살펴볼 것입니다. – Rudiger

+0

@Rudiger, 인스턴스를 유지해야하는 경우이를 사용하는 객체의 멤버로 저장하고 dealloc 메서드의 멤버에서 일반 릴리스를 사용해야합니다. –

+0

+1 클래스 메서드가 확실히 방법입니다. – TechZen

관련 문제