프로그래밍/Object-C2011. 9. 4. 14:48
객체가 생성되면 메모리가 할당되어 사용된다. 주의할 점은 객체가 필요하지 않게 될 때 잊지 말고 반드시 메모리를 해제해야 한다는 것이다. 그렇지 않으면 메모리가 반납되지 않아 메모리  누수 현상이 발생한다.

1.  지역 변수의 메모리 해제
다음의 예제를 보자. 메소드의 시작 부분에서 +alloc 메소드를 호출하여 지역 변수로 선언된 anObject1을 위한 메모리를 할당하고, 끝 부분에서 -release 메소드를 호출하여 메모리를 해제한다. 이처럼 지역 변수는 선언된 메소드 내에서만 유효하므로 메소드를 빠져나오기 전에 반드시 메모리를 해제해야 한다. 일단 메소드를 빠져나오면 지역 변수에 접근할 방법이 존재하지 않기 때문이다.




2. 인스턴스 변수의 메모리 해제
그렇다면 인스턴스 변수는 지역 변수와 어떻게 다를까, 인스턴스 변수는 일반적으로 클래스 인스턴스가 생성될 때 메모리 할당하고, 해당 인스턴스가 소멸할 때 메모리를 해제한다(모든 경우에 그러한 것은 아니다).
  소멸자는 아래와 같이 구현한다. 이때 순서가 매우 중요하므로 순서가 절대로 바뀌지 않도록 주의해야한다.



1 // 메모리를 사용하고 있는 인스턴스 변수의 메모리를 해제하는 부분. 이것으로 해당 인스턴스 변수의 레퍼런스 카운트가 0이 되어야 한다.

2 // 부모 클래스의 소멸자를 호출하는 부분. 이를 통해 부모 클래스의 소멸자, 부모 클래스의 부모 클래스의 소멸자가 연이어 호출되며, 최종적으로 루트 클래스인 NSObject 클래스의 소멸자까지 차례로 호출된다.


소멸자에 의하지 않고 다른 메소드에서 메모리 해제가 일어나는 경우도 드물지 않다.



1 // 인스턴스 변수에 저장되어 있는 값과 인자로 넘어온 값이 서로 다를 경우에만 2와 3을 실행한다.

2 // 인스턴스 변수에 할당되어 있던 메모리를 해제한다.

3 // 인자로 넘어온 객체를 retain하여 레퍼런스 카운트를 하나 증가시키고 그 주소값을 인스턴스 변수에 넣는다.

이 예에서와 같이 메소드가 실행되는 도중에 인스턴스 변수가 원래의 인스턴스 대신 다른 인스턴스를 가리키게 하려면 그전에 반드시 메모리를 해제해야 한다. 만일 여기서 2의 과정을 생략한다면 name이 원래 가리키고 있던 메모리 영역은 해제되지 못하고 계속해서 남아 있게 된다. 이런 현상을 메모리 누수라고 한다.


3. 자동으로 메모리 해제하기
메모리를 할당한 객체의 사용이 끝나면 반드시 메모리를 해제해야 한다. 그런데 메모리를 해제하는 적절한 시점을 찾기 어려운 때도 있다.



일반적으로 지역 변수를 위해 메모리를 할당한 뒤에는 해당 블록을 벗어나기 전에 반드시 메모리를 해제해야 메모리 누수를 피할 수 있다.
  이 예제에서도 지역 변수인 text를 위한 메모리 할당과 해제를 메소드 내에서 하고 있다. 하지만, 이 변수는 메소드의 반환값으로 사용될 수 없다. 이미 메모리에서 해제되었기 때문이다. release 메소드를 호출하는 부분을 삭제하면 유효한 값을 가진 text 객체를 반환할 수는 있겠지만, text 객체가 사용하던 메모리를 해제할 수 없게 된다.
  그렇다면 이럴 때는 어떻게 메모리를 해제해야 할까. autorelease 메소드를 사용하면 된다. 이 메소드는 기본적으로 release 메소드와 같은 기능을 수행하지만, 한 가지 차이점이 있다. release 메소드는 즉시 메모리를 해제하고, autorelease 메소드는 '미래의 어느 시점'에 메모리를 해제한다. 따라서 이 예에서 release 대신 autorelease를 사용하면 해당 변수가 메모리에서 바로 해제되지 않으므로 정상적인 값을 반환할 수 있다. 그리고 해당 메모리는 '미래의 어느 시점'에 해제될 것이므로 메로리 누수도 발생하지 않는다.






출처 - 도전! 아이폰4 프로그래밍





'프로그래밍 > Object-C' 카테고리의 다른 글

NSThread 예제  (0) 2011.09.04
스레드 사용하기  (0) 2011.09.04
객체 사용하기(메모리 관리)  (0) 2011.09.04
객체 생성하기(메모리 할당과 초기화)  (0) 2011.09.04
AppDelegate 전역변수 사용  (0) 2011.09.03
Posted by 건깡