2009-07-31 3 views
1

하나의 작업으로 3 가지 작업을 수행 할 수있는 이유는 무엇입니까?로터리 방식으로 속성이 될 개체를 초기화하는 이유는 무엇입니까?

UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; 

self.navigationController = aNavigationController; 

[aNavigationController release]; 

... 그리고 한 줄에 같은 일 : : 그것은 충분히하고, 간단한 청소이며, 간단 보인다

self.navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; 

여기

developer.apple.com에서 일부 코드입니다. 나는 속성이 유지되지 않는 과거의 문제를 겪었습니다. 객체 해제가 객체를 파괴 할 수 있습니다. (내가 말할 수있는 한 - 보유 속성이 설정되었습니다.) 단선 식을 사용하면 멋쟁이처럼 작동합니다.

+0

때때로 속성이 유지되지 않는 이유를 알아 냈습니다. 속성 값 (예 : self)을 설정할 때 setter 메서드 (retain 특성을 구현 함) 대신 Class 변수를 사용해야했습니다. .property = 대신 property =. 모든 도움을 주셔서 감사합니다! – JoBu1324

답변

6

목적-C memory management rulesalloc에 의해 당신이하는 개체 인스턴스 보내고 있음을 지시 (한 번 공유를 다른 개체 retain을) 인스턴스의 소유자와 메모리 누수를 방지하기 위해 소유권을 포기하고자 할 때 그래서 당신이 UINavigationControllerrelease해야한다 . 가비지 수집되지 않은 환경 (예 : iPhone)에서는 alloc 또는 copy (또는 "alloc"또는 "copy"가 포함 된 메소드)의 균형을 release 또는 autorelease으로 변경하는 것을 의미합니다. 당신은 (아이폰과 같은) 메모리 제한 환경에 autorelease을 사용하지 않으면 두 번째 조각은, 그것은 명시 적 release를 사용하는 것이 더 나은입니다

self.navigationController = [[[UINavigationController alloc] initWithRootViewController:rootViewController] autorelease]; 

될 것이다. 은 현재 NSAutoreleasePool에 수신기를 추가합니다. 수신기는 이후에 '나중에'풀의 객체에 -release을 호출합니다. 메모리 사용에 대해 조심하고 싶을 때, '미래의 어느 시점'은 좋은 생각이 아닙니다. 따라서 iPhone에서는 첫 번째 예가 표준 사용법입니다.

+0

그 경우, 문제가있다 : self가 소유자에 의해 해제되면, UINavigationController가 아닌가? – JoBu1324

+1

배리 (Barry)는 정확히 정확합니다 - 그가 언급 한 규칙을 읽으십시오. 문제는 할당 한 것이므로 릴리스해야한다는 것입니다. navigationController 속성 자체는 필요에 따라 유지하고 해제합니다. 당신이 그것을 공개하지 않으면 (두 번째 예제에서와 같이) UINavigationController가 해제되지 않고 self가 해제 된 후에도 누출되지 않는다는 것이 맞습니다. –

0

Objective-C 객체 유형의 대부분의 속성은 선언에 retain 또는 copy로 선언해야합니다. 예를 들어, 당신은 말할 수 있습니다

@property (retain) UINavigationController * navigationController; 

을 즉, 자동으로 작성 setNavigationController 기능은 당신을 위해 유지 호출하고, 한 줄이 될 경우의 경우

self.navigationController = [[[UINavigationController alloc] initWithRootViewController:rootViewController] autorelease]; 

당신은으로 실행 할 수있다 설정하려는 속성이 (보유) 또는 (복사) 대신 (할당) 사용하는 경우 문제가 발생합니다. 이 경우 setter는 포인터를 다른 포인터와 동일하게 만들고 객체의 후속 릴리스로 인해 포인터가 정리됩니다.

autorelease 대신 release를 호출하는 경우에도 문제가 발생할 수 있습니다.

희망 하시겠습니까?

0

속성을 정의한 방법에 따라 메모리 누수가 있습니다. 거의 언제든지 alloc/init 콤보를 볼 때 참조 카운트가 1 인 객체를 돌려 받고 있습니다. 속성이 retain으로 정의되었다고 가정하면 속성을 설정하면 참조 횟수가 2로 증가합니다.

당신이 정말로 이런 식으로 뭔가로 이동 한 줄에 모두 유지하려면

:

self.navigationController = [[[UINavigationController alloc] initWithRootViewController:rootViewController] autorelease]; 

은 심지어 있지만 그들을 필요 이상 주변에 원인이 될 수있는 autoreleasing 물체에 좋습니다.

+0

-autorelease는이 개체를 나중에 보내야 함을 의미합니다. 이 상황에서 -autorelease를 사용한다고해서 네비게이션 컨트롤러가 이미 고착되어 있기 때문에 필요할 때보 다 오래 걸리지 않습니다. 우리가 ivar에 할당하고 있습니다. –

+0

오른쪽 ... autorelease 단순히 현재 autorelease 풀에있는 개체에 대한 참조를 추가합니다. 실제로 풀을 비우기 위해 물이 빠져 나가기를 기다려야하기 때문에 더 오래 머무르게됩니다 (이 상황이 아님). 이 상황에서 (객체가 유지되고 있기 때문에 중요하지 않지만, 이런 방식으로 자동 회수 객체에 들어가는 것이 좋은 습관은 아닙니다. – Lounges

관련 문제