2010-05-05 7 views
9

두 가지 시나리오에서 어떤 코드가 모범 사례이며 그 이유는 무엇입니까?자동 릴리스 vs. 릴리스

오토 릴리즈

loginButton = [[[UIBarButtonItem alloc] initWithTitle:@"Login" 
               style:UIBarButtonItemStylePlain 
               target:self 
               action:@selector(loginButtonClicked:)] 
               autorelease]; 
self.navigationItem.rightBarButtonItem = loginButton; 

또는

출시하여 예를 들어

loginButton = [[UIBarButtonItem alloc] initWithTitle:@"Login" 
               style:UIBarButtonItemStylePlain 
               target:self 
               action:@selector(loginButtonClicked:)]; 
self.navigationItem.rightBarButtonItem = loginButton; 
[loginButton release]; 

답변

8

자동 해제를 사용하는 것에 대한 오명이있을 수 있습니다 (가능한 경우 언제든지 해제하는 것이 좋습니다). 그래서 나는 일반적으로 두 번째 경로로 이동합니다. 그러나 당신이 여기 루프에 있지 않기 때문에, 자동 릴리즈 이후에 대해 지금 풀어주는 것은 똑같은 효과를냅니다 (다른 객체는 loginButton을 유지 했으므로 dealloc()되지 않습니다).

하지만 대부분의 메모리 누수는 릴리스 라인을 추가하는 것을 잊어 버린 것이므로 즉시 autorelease를 사용하는 것이 좋습니다.

+3

iPhone과 같은 메모리가 부족한 장치에서는 가능한 경우 명시 적으로 해제하는 것이 좋습니다. 또한 명시 적 릴리스는 개체의 수명을 제어 할 수 있으므로 이상한 EXC_BAD_ACCESS 오류를 쉽게 디버깅 할 수 있습니다. –

+1

@Alex,이 경우 문자 그대로 아무런 차이가 없습니다. 개체는 생성 직후 보유됩니다. 일어날 모든 일은 참조 카운트가 하나씩 감산 될 것입니다. 누가 그걸 즉시 또는 나중에 언젠가는 발생하는지 신경 쓰시겠습니까? –

+0

autorelease 풀이 해제되기 전에 self.navigationItem.rightBarButtonItem을 절대로 재 할당하지 않으면 차이가 없습니다. – JeremyP

14

는, 정말 중요하지 않습니다. 개인적으로, 아마도 첫 번째 경우를 사용할 것입니다. 그러면 나중에 [loginButton release] 행을 이동하는 것에 대해 걱정할 필요없이 수정 또는 디버깅 코드를 추가 할 수 있습니다.

+1

갈 때 약간의 속도의 장점은 autorelease.So 이상 릴리스 (reference)을 사용하여 거기에? –

+2

아이폰에서 모든 경우에 autorelease가 어떻게 든 악의적 인 것처럼 느껴질 지 모르겠다. 나는 당신에게 +1을주었습니다. 왜냐하면 그가 단순히 담요 진술서를 발급 한 것이 아니라 그가 게시 한 사건을 고려하고 있기 때문입니다. 그리고 나는 당신과 같은 방식으로 느껴지기 때문에. –

+0

첫 번째 경우를 사용하면 앱이 다운됩니다.'- [UIBarButtonItem isSystemItem] : 해제 된 인스턴스에 전송 된 메시지 0x2095f2c0' –

3

Carl이 말했듯이 여러분의 경우에는 괜찮을 것입니다. UIBarButtunItem 객체가 이라는 속성을 선언했다고 가정 할 때 self.navigationItem 안에 하나의 참조가 보관되어 있기 때문에 객체가 메모리에 남아 있기 때문입니다. 따라서 autorelease 풀 사용에 대한 일반적인 비난, 즉 현재 이벤트 루프가 끝날 때까지 불필요한 객체를 메모리에 저장한다는 것은 여기에 적용되지 않습니다.

1

navigationItem은이를 유지하므로 두 끝이 동일합니다. 스타일 - 현명한, autorelease는 alloc 또는 copy를 그들의 이름으로 말하지 않는 메소드로부터의 반환에 선호된다. 그렇지 않으면 그것은 당신에게 달려있다. 객체가 별도로 유지되지 않으면 릴리스로 인해 메모리가 더 빨리 해제됩니다.

릴리스 이후에 nil에 대한 참조를 설정하는 코드 스타일 문제는 관련 질문입니다.

2

iPhone의 메모리 예산이 매우 부족하기 때문에 선호되는 방법은 명시 적 릴리스 여야합니다. 이 방법은 객체가 runloop 중에 자동 릴리즈 풀이 비워지기 전 까진 없으므로 가능한 한 작게 메모리 공간을 유지할 수 있습니다.

+2

이 비판은 생성 된 범위에서 살아남지 못할 임시 "제거 가능한"객체에만 유효합니다. 장기간 저장된 객체를 생성 할 때 객체가 해제되거나 자동으로 해제 되더라도 여전히 객체가 유지되므로 차이가 줄어 듭니다. 그러한 경우에는 더 선호하는 문제입니다. –

0

-autorelease 메시지를 개체에 보낼 때이를 목록에 추가하면 자동 풀이 풀 때 메시지가 -release이됩니다. -autorelease의 전체 목적은 당신이 공개하고있는 객체를 여전히 원할 수 있지만 당신이 보유하고 있지 않은 객체가 필요할 때 보유 및 릴리스 간의 균형을 유지할 수있는 방법을 제공하는 것입니다. 당신이 묘사하는 상황에서, 당신이 준 두 번째 예제가 더 좋습니다.

0

비록 제시된 시나리오 두 경우는 동일하지만 엄격한 성능 요구 사항이 downvote에 대한 모든 설명이 릴리스