Objective-C 기초

ARC, Objective-C 메모리 관리 방법

nightohl 2019. 2. 15. 17:58
반응형

Objective-C 메모리 관리 방법


프로그램을 실행시킬 때 프로그램을 메모리에 올려서 메모리에서 CPU와 상호작용하며 프로세스로 돌아감.

그런데 메모리가 부족하다면? 새로운 프로그램은 실행되지 않을 수도 있고 동작중이던 프로세스도 뻗어버리기도 하며 메모리가 확보될 때까지 무한정 루프를 돌기도 하고 또한 운영체제에서 필요한 프로그램을 실행시키기 위해 다른 앱을 강제종료 시키기도 함.

요약 ==> 프로그램이 돌아가는 데에 악영향을 끼침.


원활히 여러 프로그램들이 동작하려면 메모리가 잘 관리가 되어야함.

어떻게?


사용중인 객체는 사용중이라고 표시! ==> 소유(Own)

소유된 횟수는 '참조 카운'에 저장됨.

==> 참조 카운트가 0이라면 -> 더 이상 사용하지 않는군! -> 해제


초기에는 리테인 카운터를 수동으로 증가,감소 시켰음 -> 사람의 손을 많이 탐 -> 오류가 많이 생김.


iOS 5 부터 ARC(Automatic Reference Counting)기술을 통해 자동으로 메모리 관리.



[ 객체 소유하기 ]

: 객체를 포인터 변수로 받으면 '소유한다(retain)' 라고 함.

ex) NSObject *myObj = [[NSObject alloc] init];

객체를 할당, 초기화 받고 이것을 객체 포인터 변수에 담았음. -> 소유 -> 참조 카운트 자동 증가.


ex) myObj = nil;

이렇게 포인터 변수가 비게 되면 -> 참조 카운트가 자동 감소. -> 참조 카운트가 0이라면 -> 자동 해제.

★모든 포인터 변수가 객체를 '소유'하진 않음. (생존주기 수식자(Lifetime Qualifier)에 의해 정의됨)


배열, 딕셔너리 등의 콜렉션에 객체를 넣을 경우, 콜렉션도 객체를 소유함.

=> 하나를 nil 하더라도 객체가 해제되지 않음. (리테인 카운터가 1 이상이니까!)


[생존주기]

객체 생성 -> 힙 영역 할당 -> 일부러 해제하지 않는 이상 유지됨 -> 소유가 0이라면 ->  ARC가 자동으로 해제.  


포인터 변수도 변수이므로 공간 할당, 해제 과정 필요 -> 포인터변수의 생존주기는 어떻게 될까?

포인터 변수는 지역변수, 멤버변수(프로퍼티)로 구성됨. 

지역변수는 선언된 코드 단위가 종료하면 사라짐.

멤버 변수는 객체가 해제되면 사라짐.


[ 생존주기 수식자 ]

모든 포인터가 객체를 소유하진 않는다고 했다. 객체를 소유하는, 소유하지 않는 생존주기 수식자들을 살펴보자.

[객체를 소유하는 포인터]
1) strong. - default이므로 생략 가능.
프로퍼티
@property (strong) NSString *strongPtr;
멤버 변수, 스택 변수 (언더바 2개)
NSObject __strong *strongPtr

[객체를 소유하지 않는 포인터]
2) weak
3) unsafe_unretained
프로퍼티
@property (weak) NSString *strongPtr;
멤버 변수, 스택 변수 (언더바 2개)
NSObject __weak *strongPtr
★ 객체를 소유하지 않기 때문에 참조 카운트가 증가하지 않음 -> strong없이 weak로만 생성한다면 -> 생성과 동시에 해제됨. (참조 카운트가 0이므로 사용하지 않는다고 간주)

[ weak와 unsafe_unretained의 차이 ]
포인터 변수는 주소를 담음.
객체가 해제 됐다 하더라도 주소값을 통해서 해제된 '영역'에 접근 가능. ==> bad access !!
weak는 해제 -> 포인터 변수에 nil을 넣음.(편안 ^__^)
unsafe_unretained는 해제 -> 포인터 변수에 주소값 그대로 유지. (해제된 메모리 공간 접근에 주의)

4) autoreleasing
포인터의 주소로 객체를 전달. 즉, 일반적인 리시버가 전달을 받는 상황이 아니라 리시버가 센더에게 메시지를 보냄
주로 NSError에서 사용됨.


[ 제약 사항 ]

1) 프로퍼티 이름은 new로 시작 못함

2) 강한 순환 참조 주의

서로가 서로를 강한 참조로 소유할 경우, 객체가 해제되지 않아 메모리 확보 불가.

3) 수동으로 참조 카운트 관련 메소드 사용 금지

 -(id)retain

 -(void)release

 -(id)autorelease

 -(NSUInteger)retainCount

4)메모리 해제 용도로 dealloc 사용 금지



 


반응형

'Objective-C 기초' 카테고리의 다른 글

클래스 내부 구성요소 숨기기  (0) 2019.02.15
카테고리 Category  (0) 2019.02.15
콜렉션 특징  (0) 2019.02.15
NSSet  (0) 2019.02.15
NSDictionary  (0) 2019.02.15