2011-09-02 5 views
1

IOS 개발을 살펴보기 시작했고 참조를 저장하지 않은 객체를 릴리스 할 때 몇 가지 의구심이 있습니다. " 바늘?" 즉시 생성 한 후 객체에 오토 릴리즈 메시지를 보내도록 제안하고, 그래서 나는 다음과 같은 코드 조각에 동일한 작업을 수행하려고 여기서오류 발생시 자동 생성 객체가 생성 된 후

int main(int argc, char *argv[]) 
{ 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
    NSURLResponse * response = nil; 
    NSError * error = nil; 
    NSData * data; 

    data = [NSURLConnection 
      sendSynchronousRequest: [[NSURLRequest requestWithURL: 
             [[NSURL URLWithString: @"http://www.google.it"] 
              autorelease] 
            ] autorelease] 
       returningResponse: &response 
          error: &error]; 

    [data writeToFile: @"/tmp/test.html" 
      atomically:NO]; 

    [data release]; 
    [pool drain]; 

    return 0; 
} 

나는 아직 엑스 코드에서 프로그램을 실행하려고하지 수 ,하지만 리눅스에서 컴파일 해요 및 NSURLRequest 개체를 보낸 autorelease 메시지를 세분화 오류가 발생합니다 (나는 그것이 메시지 자체에 의해 원인이 아니라 개체를 풀어보십시오 autorelease 메시지로 인해 발생한다고 생각합니다) . NSURLRequest 객체에 보낸 autorelease 메시지의 문제점은 무엇입니까?

requestWithUrl과 같은 클래스 메소드의 참조 문서에서 "URL 요청을 생성하고 반환합니다"라고 말하면 사용을 마쳤을 때 객체를 릴리스해야한다는 의미입니다. ? 나는이 메모리 관리 규칙을 더 잘 이해하기를 원한다. 내 질문이 너무 바보가 아니길 바란다 .--)

어, 마지막 질문 하나만 : 오류와 데이터도 공개해야합니까? 동기식 요청에 의해 반환 된 객체?

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

답변

3

+requestWithURL: (및 기타) 메서드는 이미 자동 렌더링 된 객체를 반환하므로 하나 이상의 자동 회수를 보내지 않아야합니다.

코드에있는 추가 자동 응답 기능을 사용하면 나중에 객체가 과중 릴리스되어 앱이 다운 될 수 있습니다.

개체를 릴리스해야하는지 여부를 아는 규칙 - 해당 이름에 'alloc', 'new', 'copy'가 포함 된 메서드를 사용하여 개체를 만드는 경우에만 필요합니다. 모든 표준 API는이 규칙을 따르므로 사용자 고유의 메서드를 개발할 때는 표준 API를 따라야합니다.

그래서 수정 된 코드는 다음과 같습니다

int main(int argc, char *argv[]) 
{ 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
    NSURLResponse * response = nil; 
    NSError * error = nil; 
    NSData * data; 

    data = [NSURLConnection 
      sendSynchronousRequest: [NSURLRequest requestWithURL: 
              [NSURL URLWithString: @"http://www.google.it"]                     
       returningResponse: &response 
          error: &error]; 

    [data writeToFile: @"/tmp/test.html" 
      atomically:NO]; 

    [pool drain]; 

    return 0; 
} 

P.S. 위의 이유로 데이터와 오류 개체를 모두 릴리스해야합니다.

+0

즉각적인 답변을 보내 주셔서 감사합니다. 나는 그들이 autoreleased되었다고 의심, 이제 모든게 훨씬 명확 : 만약 내가 그것을 release (또는 나중에 autorelease 위해 그것을 표시해야합니다) 무언가를 할당, 내가 + requestWithUrl 같은 클래스 메소드를 사용하여 인스턴스를 만들면 (그 init 포함되지 않습니다/copy/new words) 어떤 이유로 든 그것을 보관하지 않으면 나는 그것을 풀어서는 안된다. –

+0

@ 지아 니스, 정확히! :) – Vladimir

1

코드는 다음과 같아야합니다

int main(int argc, char *argv[]) 
{ 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
    NSURLResponse * response = nil; 
    NSError * error = nil; 
    NSData * data; 

    data = [NSURLConnection 
      sendSynchronousRequest: [NSURLRequest requestWithURL:[NSURL URLWithString: @"http://www.google.it"]] returningResponse:&response error: &error]; 

    [data writeToFile: @"/tmp/test.html" 
      atomically:NO]; 

    [pool drain]; 

    return 0; 
} 

당신은 그 방법으로 생성하여 객체에 autorelease를 호출 할 필요는 없다 \

당신은 dataerror을 해제 할 필요가 없습니다..

NSClass *object = [NSClass classSomeMagicWords];을 사용하여 객체를 반환하는 모든 메서드는 자동 렌더링 된 객체를 반환하므로 retain을 호출하지 않으면 해제하면 안됩니다.

0

자동 변소 쇠를 제거해야합니다. iOS/Mac OSX 개발자의 경우 Apple에서 제공하는 클래스를 사용하면 init이라는 단어가 포함되지 않은 메서드로 객체를 만드는 경우 이미 자동 렌더링 된 객체가 제공된다는 규칙이 있습니다.예를 들어

:

NSString *blaah = [[NSString alloc] init]; 

은 나중에 공개 할 필요가 객체를 반환합니다.

NSURL *googlelink = [NSURL URLWithString: @"http://www.google.it"]; 

다른 한편으로는 자동 출시 개체를 제공 할 것이며 다시 해제하면 충돌이 발생합니다.

0

iOS 메모리 관리에서는 작성한 객체 만 소유하거나 객체를 복사하거나 (alloc으로 시작하거나 이름에 "copy"가있는) 객체를 복사하여 만듭니다.

당신이 소유하고 있다면 자동으로 풀어 줄 필요가 있습니다. requestWithURL 또는 URLWithString과 같은 메서드는 이미 자동 렌더링 된 객체를 반환합니다.

자세한 내용은 Apple 개발자 사이트의 this doc을 확인하십시오.

관련 문제