2010-01-05 7 views
4

이 코드를iPhone 앱에서 메모리를 안정적으로 해제하려면 어떻게해야합니까?

NSString *postData = [@"foo=" stringByAppendingString:fooText.text]; 
... 
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url]; 
... 
[postData release]; //this causes crash 
[request release]; //this causes crash 

이있는 경우 지금은 이것이 expected behavior according to Apple's documents 이해. 이제 릴리스 코드를 제거하면 크래시가 발생하지 않지만 어쨌든 * 요청에 대해 메모리 누수가 발생합니다. 그래서 나는 코드를 다시 작성한다.

NSString *postData; 
//postData = [NSString alloc]; // this line commented out since OP 
postData = [@"foo=" stringByAppendingString:fooText.text]; 
... 
NSMutableURLRequest *request; 
request = [NSMutableURLRequest alloc]; 
request = [request initWithURL:url]; 
    ... 
    [postData release]; //this still crashes # 
    [request release]; //this works fine 

#가 추락하는 이유를 정말로 모른다. 여기에 권장되는 모범 사례가 있습니까? 나는 종종 '속기'접근법 (맨 위에)이 공개되어 (Kochan, Objective-C 프로그래밍) 예를 들어보기 때문에 무언가를 놓치고 있다고 생각하지만, Apple docs는 그것이 잘못되었다고 말한다.

답변

7

일반적으로 헬퍼 정적 메서드 (예 : stringByAppendingString)를 호출하는 경우에는 해제하지 않아야합니다. 그 문자열은 당신에게 주어지기 전에 자동 풀 풀에 추가되었습니다. alloc 다음에 init... 메서드를 호출하는 경우 해당 개체를 해제해야합니다. 코드에서주의 할

다른 것들 : 두 번째 예에서

  • , 당신은 즉시 stringByAppendingString에 의해 만들어진 다른 문자열로 교체, postData를을 ALLOC, 그 메모리 누수입니다.
  • 귀하의 릴리스 호출은 [postData release][request release]
  • 난 당신이 두 사람과에서 점점 정확히 확신하지, 당신의 예에서 postDatarequest 사이의 상관 관계를 보이지 않는해야한다, 잘못입니다.
+1

"일반적으로 헬퍼 정적 메서드 (예 : stringByAppendingString)를 호출하는 경우이를 해제하면 안됩니다." 그게 내가 찾고 있던거야!그러나 악기가 메모리 누수가 있음을 나타내는 경우 (첫 번째 예제에서는 * 모두가 간단한 메소드 안에 있음) 주어진 * 요청을 어떻게 풀려고합니까? 이것은 autorelease가 * 요청을 위해 작동하지 않았다는 것을 나타내는 것 같습니다. – Gazzer

+0

첫 번째 예에서는 사용자가 직접 요청을 할당하고 입력 했으므로 릴리스해야합니다. 당신이 할 때 당신이 겪는 충돌은 무엇입니까? EXC_BAD_ACCESS? 이는 대개 이미 요청한 것을 (또는 요청한) 요청을 의미하고 사용자는이를 인식하지 못했습니다. –

0

개체에 대한 메모리를 할당하고 더 나은 하나의 라인에서 수행 초기화 - 다른 객체를 반환 할 수 있습니다 init 메소드 또한 당신이 2 예에서 변경 한 실수를 방지하는 데 도움이 될 수 있습니다 :

NSString *postData; // Define pointer to string 
postData = [NSString alloc]; // Allocating nsstring pointer and assign it to variable 
postData = [@"foo=" stringByAppendingString:fooText.text]; // assign to postData new **autoreleased** string object. result of the previous assignment is abandoned. 
[postData release]; //so here you release autoreleased object!! 

내가 할 수없는 그림 왜 [평평한 방출]; 첫 번째 예제에서는 충돌이 발생합니다.

P. 완전히 깨어 나지 않았거나 [release postData] 대신 [postData release]이되어야합니까?

1

첫째, 두 번째 예에서 postData = [NSString alloc]; 행은 완전히 필요하지 않습니다. postData은 다음 행으로 덮어 씁니다. 둘째, 상황이 왜 잘못되었는지에 대한 답변을 제공합니다. 좋은 대답은 없습니다. 시스템은 보유 횟수가 0이 된 후에도 언제든지 메모리를 확보 할 수 있습니다. 문제를보다 쉽게 ​​디버그하려면 NSZombieEnabled을 켜야합니다. 할당 해제 된 모든 오브젝트를 낙서하여 충돌을 테스트 할 수있는 100 % 신뢰할 수있는 방법을 제공합니다.

또한/init을 별도의 줄에 할당하는 것은 좋지 않은 스타일입니다.

일반적으로 메모리 지침을 따르는 데 집중해야합니다. 가이드 라인을 따르지 않으면 행동이 정의되지 않을 수 있습니다.

-1
NSString *postData; 
postData = [[NSString alloc]init]; 
postData = [@"foo=" stringByAppendingString:fooText.text]; 
... 
NSMutableURLRequest *request; 
request = [[NSMutableURLRequest alloc]initWithURL:url]; 
... 
    [postData release]; 
    [request release]; 

시도해보십시오.

+0

귀하의 예는 여전히 원래 질문 – Vladimir

+0

에서와 같이 postdata에서 동일한 문제가 있습니다. [postData release]를 추가하는 것이 더 좋습니다. 그 변수를 사용하자마자 사용 후 메모리를 해제해야합니다. – Nithin

+1

postData에는 3 번째 줄에 자동 할당 된 객체가 포함되어 있습니다.이를 풀어서는 안됩니다. 두 번째 줄에 문자열을 할당하면 누수되므로 단순히 덮어 씁니다. – Vladimir

관련 문제