자동 다시 렌더링 된 객체를 nil로 설정하는 것이 안전합니까? autoreleased 객체를 해제 할 필요는 없지만 메모리 사용을 최소화하기 위해 객체를 즉시 해제하려면 객체를 nil로 설정할 수 있습니까?Objective-C : 자동 다시 렌더링 된 객체를 0으로 설정
나는이 책을 잠시 후에 읽었을 지 모르지만 나는 그것을 기억하는 것이 안전하다는 것을 기억하고 싶지 않다.
자동 다시 렌더링 된 객체를 nil로 설정하는 것이 안전합니까? autoreleased 객체를 해제 할 필요는 없지만 메모리 사용을 최소화하기 위해 객체를 즉시 해제하려면 객체를 nil로 설정할 수 있습니까?Objective-C : 자동 다시 렌더링 된 객체를 0으로 설정
나는이 책을 잠시 후에 읽었을 지 모르지만 나는 그것을 기억하는 것이 안전하다는 것을 기억하고 싶지 않다.
나는 근본적인 무언가를 놓치고 있다고 생각합니다. 개체를 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
에게 안전하게 메시지를 보낼 수 있습니다. 그러나 변수를 "제외"하지 않으면 나쁜 결과가 발생할 수 있습니다. foo
이 MyObject
인스턴스를 가리킨 다음 MyObject
인스턴스가 삭제되었다고 가정하면 (release
이지만 nil
으로 설정하지 않은 경우) foo
에서 메소드를 다시 호출하려고하면 앱이 중단됩니다. foo
을 nil
으로 설정하면 앱이 재미있게 계속됩니다. 은 당신이 원하는 바를 할 수는 없지만 그것은 완전히 다른 문제입니다.
멋진 Objective-C 메모리 관리 세계에 오신 것을 환영합니다.
* 로컬 블록을 제외한 나머지 블록은 복사 될 때까지만 남아 있습니다. 이것에 대한 몇 가지 다른 경고가 있지만, 그것은 비밀에 부딪 히고 있습니다.
예, 이것은 개체가 사용되지 않았 음을 나타내는 우수 사례입니다. 즉, 참조 된 데이터가 없습니다.
가치가있는 부분은 Apple의 샘플 코드에서도 많이 볼 수 있습니다.
자동 회수 풀과 가비지 수집기를 혼동하는 것 같습니다. GC 환경에서는 그렇지 않으면 영속적 인 객체 참조를'nil'으로 설정하는 것이 좋습니다. 하지만 GC는 종종 Mac에서도 사용되지 않으며 iOS에서는 사용할 수 없습니다. 불필요한 코더를 잡기 위해 부실 포인터가 남아 있지 않도록하는 등,'nil '을 설정하면 잠재적 인 이점이 있지만 메모리 관리에는 영향을 미치지 않습니다. – walkytalky
@walkytalky가 동의했습니다. 나는 GC에 대해 아무 말도하지 않았다. 나는 방금 그것이 좋은 습관이라고 언급했다. 당신이 언급 한 것과 같은 이유로 청결을 보장합니다. –
충분합니다. 그러나이 경우 "메모리 풀이 사용되지 않는다는 것을 알 수 있습니다. 즉, 참조 된 데이터가 없음"이라는 말이 무슨 뜻인지 알기가 어렵습니다. – walkytalky
자동 실행 취소 된 개체를 nil로 설정하면 안전하며 경우에 따라 코드로 의도를 표시하는 데 도움이됩니다. 그러나 객체를 nil로 설정해도 객체가 즉시 해제되지는 않습니다. autorelease pool이 고갈 된 후에 만 풀려날 것입니다. –
'[pool drain]; ' – Adrian
매우 배가 고픈 프로세싱의 메모리 관리에 관해서 이해하는 것은 매우 중요한 개념이다. 이 점을 분명히 밝히지 않은 객관적인 연구가 많이 있습니다. ARC와 Java 같은 전통적인 가비지 수집 모델을 혼동시킬 수있는 많은 개발자가 있다고 생각합니다. 나는 그것에 대한 나의 이해가 정확하다는 것을 확인하게되어 기쁘다. 심지어 나는 그것에 대해 질문을했기 때문이다. –