RC
Reference Counting (Retain Count)
- 애플에서 사용하는 메모리를 관리 방식
- 각각의 객체에 리퍼런스 카운트값을 부여해 해당 객체가 몇번 참조 되고 있는지를 판단할 수 있다
- 객체의 RC값으로 메모리 해제 시점을 파악
참조시 해당 객체의 RC는 1 증가한다
참조 해제시 해당 객체의 RC는 1 감소한다
객체의 RC 값이 0이 되는 즉시 해당 객체를 메모리에서 해제시킨다
* RC 증감 함수 *
-------------------- RC (+1) ----------------------
- alloc
: 객체 생성과 동시에 메모리 할당하는 함수
- new
: new = alloc + init
- copy, mutableCopy
: 객체의 복사본을 만든 후, 복사본의 RC를 증가시키는 함수
- retain
: 단순히 해당 객체의 RC를 증가시키는 함수
-------------------- RC (-1) ----------------------
- release
: 단순히 해당 객체의 RC를 감소시키는 함수
- autorelease
: autoreleasepool에 해당 객체를 넣어두고, release 해야하는 시점에 알아서 처리됨
: autoreleasepool이 메모리에서 사라질 때 객체도 동시에 사라짐
* autoreleasepool *
각각의 autorelease된 참조 객체를 pool에서 보관하고 있다가 rc가 0이 되는 시점에서 모든 참조객체로 한번에 release 메시지를 보내는 것
함수에서 객체를 반환할 때, 유용하게 쓰인다
(예시)
NSString *firstStr = nil;
// [RC = nil]
firstStr = [[NSString alloc] initWithFormat:@"hello"];
// [RC = 1]
NSString *secondStr = [firstStr copy];
// [RC = 2]
[firstStr release];
// [RC = 1]
NSString *thirdStr = [NSString stringWithFormat:@"hi"];
// [RC = 1]
* NSString *
1. 객체 생성자 (예시) [[NSString alloc] initWithFormat:@"hi"];
- 객체 생성과 동시에 RC가 1로 설정됨
- 단, 개발자가 생성한 객체이므로 release할 책임이 개발자에게 있음
2. 간편 생성자 : (예시) [NSString stringWithFormat:@"hi"];
- alloc이나 init을 사용하지 않아 RC가 증가 하지 않음
- retain 함수를 호출해 해당 객체의 RC값을 +1 해줘야 함
- 간편 생성자는 객체 자체적으로 release하므로 개발자가 release해 줄 필요는 없다
(stringWithFormat 함수 내에서 autorelease 해줌, autoreleasepool이 release 알아서 처리)
( TIP )
1. alloc/new/copy/retain 의 갯수와 release/autorelease 의 갯수가 동일 해야함
2. alloc/new/copy로 시작하지 않는 메시지로 생성된 오브젝트는 내버려두면 자동적으로 해제됨(간편 생성자)
3. 간편 생성자로 생성된 객체 중에 자동으로 해제되면 곤란한 경우, retain 호출 (단, release 알아서 처리해주기)
4. 객체 생성자로 생성된 객체를 자동으로 해제하고 싶을 땐, autorelease 메시지를 보내면 됨
5. retain, release 메시지는 RC를 즉석에서 증감시키지만, autorelease는 지연하면서 RC를 감소 시킨다.
6. 함수의 파라미터로 객체가 사용될 때, 해당 객체의 RC(+1)되며, 메소드 종료시 RC(-1) 됨
MRC & ARC
1. MRC
Manual Reference Counting, 수동 메모리 관리 방식
retain/release... 과 같이 개발자가 코드로 직접 RC(메모리) 관리하는 방식
2. ARC
Automatic Reference Counting, 자동 메모리 관리 방식
release, retain, retainCount, autorelease를 사용할 수 없다 (자동으로 관리해줌)
Xcode
* Xcode(Objective C)에서 ARC/MRC 설정하는 법
Xcode Project > Build Settings > Apple LLVM 9.0 - Language - Objective C > Objective-C Automatic Reference Counting > Yes(ARC) / No(MRC)
메모리 누수 & 댕글링 포인터
1. 메모리 누수 (Memory Leak)
메모리를 불필요하게 많이 할당하고 있는 경우, 메모리 누수 현상이 발생
retain/alloc 을 너무 많이 하면, 메모리 누수가 발생
2. 댕글링 포인터 (Dangling Pointer)
데이터 값이 없는 껍데기 포인터가 생성되면, 그 포인터는 댕글링 포인터가 된다.
release 를 너무 많이 하면, 댕글링 포인터가 발생
메모리 구조
1. Stack
- 지역변수, 매개변수가 저장되는 공간
- OS가 메모리 관리
- 메모리 사용 크기 가변
- Stack Overflow 주의
: 하지만 제안된 양의 주소공간 이상을 사용할 때, 발생
: 프로그램 충돌을 발생시킨다
: 무한 루프/재귀함수/Exception발생으로 지역변수나 매개변수가 제대로 unwind되지 않은 경우 스택 오버플로우 발생
2. Heap
- 객체가 저장되는 공간
- 동적 할당
- 메모리 관리 대상 (ARC/MRC로 관리)
- 메모리 사용 크기 가변
3. Data
- 초기값이 있는 전역변수가 저장되는 공간
- 프로그램 종료시 해제됨
- 메모리 사용 크기 고정
4. Code(Data)
- 프로그램 코드가 저장되는 공간
- 프로그램 종료 시 해제됨
- 메모리 사용 크기 고정
* 메모리 구조에서의 객체 인스턴스 *
- 객체 포인터는 Stack 영역에 저장 됨
- 객체 자체는 Heap 영역에 저장 됨
- Stack에 저장되어 있는 객체의 포인터 주소로는 Heap 영역에 저장되어 있는 메모리 주소값과 해당 주소의 객체가 유효한지 알 수 없음
- Stack에 이미 해제된 객체의 메모리 주소값이 저장되어 있을 수 있음 (reference count로 관리)
참고 사이트
- MRR(MRC) : retain, release, autorelease
- ARC : weak, strong, unowned
- 멀티스레딩 : atomic, nonatomic
- ARC
'iOS' 카테고리의 다른 글
[iOS] Xcode 업로드 오류 해결법 (App Store Connect 업로드 불가) (0) | 2020.09.21 |
---|---|
[Firebase] Firebase Cloud Messaging (FCM) (0) | 2020.08.16 |
[Apple Developer] 인증서 (0) | 2020.08.12 |
[Objective-C] 클래스 구조(.h 와 .m) & 메소드 (0) | 2020.08.12 |
Objective-C와 Swift 비교 (0) | 2020.08.12 |