2010-07-05 5 views
3

자동 다시 렌더링 된 객체를 nil로 설정하는 것이 안전합니까? autoreleased 객체를 해제 할 필요는 없지만 메모리 사용을 최소화하기 위해 객체를 즉시 해제하려면 객체를 nil로 설정할 수 있습니까?Objective-C : 자동 다시 렌더링 된 객체를 0으로 설정

나는이 책을 잠시 후에 읽었을 지 모르지만 나는 그것을 기억하는 것이 안전하다는 것을 기억하고 싶지 않다.

+1

자동 실행 취소 된 개체를 nil로 설정하면 안전하며 경우에 따라 코드로 의도를 표시하는 데 도움이됩니다. 그러나 객체를 nil로 설정해도 객체가 즉시 해제되지는 않습니다. autorelease pool이 고갈 된 후에 만 ​​풀려날 것입니다. –

+1

'[pool drain]; ' – Adrian

+0

매우 배가 고픈 프로세싱의 메모리 관리에 관해서 이해하는 것은 매우 중요한 개념이다. 이 점을 분명히 밝히지 않은 객관적인 연구가 많이 있습니다. ARC와 Java 같은 전통적인 가비지 수집 모델을 혼동시킬 수있는 많은 개발자가 있다고 생각합니다. 나는 그것에 대한 나의 이해가 정확하다는 것을 확인하게되어 기쁘다. 심지어 나는 그것에 대해 질문을했기 때문이다. –

답변

15

나는 근본적인 무언가를 놓치고 있다고 생각합니다. 개체를 nil으로 설정하면 메모리 관리 측면에서 아무런 효과가 없습니다. 여기에 무슨 일이 있습니다 : alt text http://gallery.me.com/davedelong/100084/Pointers1/web.png?ver=12783505480001

이 이미지에는 스택이 있습니다 (로컬 변수가있는 곳, 실행 중 코드에있는 것과 거의 같은 의미입니다). int bar = 42;과 같은 것을 선언하면 bar이 스택에 있습니다. 오른쪽에는 힙이 있습니다. 이것은 응용 프로그램에 속하는 전역 메모리 공간입니다. 힙은 범위의 문제를 해결하기 위해 발명되었습니다. 현재 유용한 기능 (또는 방법)의 범위를 벗어나는 유용한 정보를 만드는 법. 우리가 malloc 공간 일 때, 우리는 힙에 메모리 슬롯을 할당받습니다. alloc/init 개체가있을 때 해당 개체는 힙에 있습니다. Objective-C에서 모든 객체는 힙에 살고 있습니다. *이 줄을 생각해 봅시다 :

MyObject * foo = [[MyObject alloc] init]; 

정말 두 가지 일이 있습니다. 첫 번째는 MyObject 구조를 유지하기에 충분히 큰 힙에 새로운 덩어리 (alloc)를 할당했다는 것입니다. 그런 다음 해당 청크의 위치를 ​​가져 와서 foo이라는 로컬 변수에 할당했습니다. 위 이미지에서 왼쪽의 붉은 색 원은 foo이고 오른쪽의 붉은 색 얼룩은 모든 데이터와 함께 실제 MyObject입니다. 지금까지 이해가 되니?

다음은 "nil에 개체를 설정"할 때 발생하는 상황 (foo = nil;) alt text http://gallery.me.com/davedelong/100084/Pointers2/web.png?ver=12783505490001

당신은 객체 여전히 힙에 살고있는 것을 볼 수 있습니다. 실제로 변경된 유일한 것은 로컬 변수 foo이 더 이상 힙의 메모리 덩어리를 가리 키지 않는다는 것입니다. 이는 0 (nil, NULL, 원하는 것을 지정)을 가리키며, 이는 "더 이상 관련이없는 항목"을 가리키는 방식입니다.

간단히 : 변수를 nil로 설정하면 메모리 관리과 아무 관련이 없습니다. 즉시 객체를 제거하려면 autorelease이 아니라 release을 사용하십시오. 그러나 그때조차도 "즉시 파괴"를 보장하지는 않습니다. 그 이유는 객체가 retain이 될 수도 있기 때문입니다 (전체 유지 지점 보존 메모리 관리 모델 사용). 당신이 객체와 완료 (그리고 당신도 release 또는 autorelease를 호출 한 후) 일단이 넘어

는, 그것은 여전히 ​​잠재적 인 문제를 방지하기 위해, nil에 변수를 설정하는 것이 좋습니다.Objective-C에서 우리는 (자바와는 달리) 우리의 얼굴에 물건이 날아 가지 않고도 nil에게 안전하게 메시지를 보낼 수 있습니다. 그러나 변수를 "제외"하지 않으면 나쁜 결과가 발생할 수 있습니다. fooMyObject 인스턴스를 가리킨 다음 MyObject 인스턴스가 삭제되었다고 가정하면 (release이지만 nil으로 설정하지 않은 경우) foo에서 메소드를 다시 호출하려고하면 앱이 중단됩니다. foonil으로 설정하면 앱이 재미있게 계속됩니다. 은 당신이 원하는 바를 할 수는 없지만 그것은 완전히 다른 문제입니다.

멋진 Objective-C 메모리 관리 세계에 오신 것을 환영합니다.

* 로컬 블록을 제외한 나머지 블록은 복사 될 때까지만 남아 있습니다. 이것에 대한 몇 가지 다른 경고가 있지만, 그것은 비밀에 부딪 히고 있습니다.

+1

삽화를 들고 올라간다. +1. – bbum

+0

@bbum i <3 omnigraffle. 나는 또한 단어와 스택과 힙을 설명하려고하면 사람들을 혼란스럽게하는 경향이 있음을 발견했습니다. (적어도 나에게 해줬 다 : 계속하고 있었던 일을 시각화하는 것은 그것이 모두 클릭되었을 때였다) –

+0

나는 이미지가 404가 아니 었으면 좋겠다. (mobileMe closed shop 이후). 나는 시각적 인 학습자이다! :) 어쨌든, 굉장한 대답, upvoted! – taber

0

예, 이것은 개체가 사용되지 않았 음을 나타내는 우수 사례입니다. 즉, 참조 된 데이터가 없습니다.

가치가있는 부분은 Apple의 샘플 코드에서도 많이 볼 수 있습니다.

+0

자동 회수 풀과 가비지 수집기를 혼동하는 것 같습니다. GC 환경에서는 그렇지 않으면 영속적 인 객체 참조를'nil'으로 설정하는 것이 좋습니다. 하지만 GC는 종종 Mac에서도 사용되지 않으며 iOS에서는 사용할 수 없습니다. 불필요한 코더를 잡기 위해 부실 포인터가 남아 있지 않도록하는 등,'nil '을 설정하면 잠재적 인 이점이 있지만 메모리 관리에는 영향을 미치지 않습니다. – walkytalky

+0

@walkytalky가 동의했습니다. 나는 GC에 대해 아무 말도하지 않았다. 나는 방금 그것이 좋은 습관이라고 언급했다. 당신이 언급 한 것과 같은 이유로 청결을 보장합니다. –

+0

충분합니다. 그러나이 경우 "메모리 풀이 사용되지 않는다는 것을 알 수 있습니다. 즉, 참조 된 데이터가 없음"이라는 말이 무슨 뜻인지 알기가 어렵습니다. – walkytalky

관련 문제