안녕하세요 소들입니다 :)
오늘은 iOS 메모리의 3번 째 시간!
음... 사실 Swift에선 MRC를 사용할 일은 없어요
왜냐면 Swift는 오직 ARC만 제공하닊하...
근데 옵젝씨는 MRC를 프로젝트 통째로,
혹은 파일 별로도 선택할 수 있어여 :)
(파일별로 되는지는 해본 적 없는데 공식 문서에서 그랬음..)
그래서 저는... 옵젝씨도 다루기 때문에
이들에 대해 한번쯤 짚고 넘어가보려고 합니다!!!
(우리 회사 레거시 코드들에 아직 MRC 흔적ㅇ ㅣ남아있기 때문..ㅎㅎ뷁)
ARC에 대해 모르시는 분이 보면 이해하기 힘들 수 있으니
제 이전 포스팅들을 보고 오는 것을 추천해 드립니다..
이번 포스팅은 Objective-C로 설명할 거라
만약 관심 없다하면 스킵하셔도
무방합니다
ㅌㅌ
1. MRR/MRC
먼저 정의에 대해 알고 가봅시당 :)
이전 포스팅을 보신 분들은 알겠지만
MRC와 ARC는 Reference Count를 통해 메모리를 관리 한단 것에서 동일하지만
수동으로 RC를 계산 vs 자동으로 RC를 계산
이라는 차이점이 있었음!! ㅎㅎ
그러면 어떻게 RC(참조 횟수)를 직접 계산할까!?
자, 먼저 MRC를 사용하기 위해서
프로젝트 Build Settings 에 들어가주셈
이 부분을 No로 선택하면
자동으로 MRC로 변경 됨
1-1. 참조 횟수 Count Up (+)
먼저,,,,
우린 ARC에서 RC를 Reference Count 라고 불렀잖음!?
근데 MRC에선 Retain Count 라고 부르나봄
MRC의 경우 개발자가 직접 count를 해서인지
인스턴스에 대한 RC에 접근할 수 있는 프로퍼티가 존재하는데,
그 프로퍼티의 이름이 retainCount 임
(ARC는 당연히 없음!)
또한 MRC를 retain/release 개념으로 생각해서
MRR(Memory Retain Release)
라고도 부르는 것 보면 Retain Count 가 맞는듯 ㅎㅎ
그래도 간편하게 RC로 통일해서 부르겠음!!
① 인스턴스를 새로 생성할 때
Objective-C에서 인스턴스를 새로 생성하는 방법엔 다음과 같은 메서드들이 있음
alloc |
new |
copy |
mutableCopy |
만약 다음과 같이 test란 인스턴스를 새로 생성하면
메모리엔 다음과 같이 할당 됨
띠용? 수동인데 왜 할당 메서드 썼다고 RC가 자동으로 +1이 된거지?
실제로 test 인스턴스의 RC를 출력해보면
+1이 지정되어 있음!!!!
따라서 새로 인스턴스를 생성할 경우 RC가 자동으로 증가함
인스턴스를 새로 생성한 경우, ARC처럼 자동으로 증가되는 것임
엥? MRC는 수동으로 증가시키는 건데?
이제 수동으로 증가시키는 경우를 봐볼거셈 :))
② retain 메서드를 사용할 때
RC를 수동으로 증가시키는 방법은 retain 메서드를 쓰는 것임
retain |
예제로 보자 :D
retain 메서드를 다음과 같이 사용하면
RC 값이
증가 함!!!
처음 인스턴스 생성 시 자동으로 +1이 증가,
retain 함수를 호출함으로써 +1이 증가
그럼 retain 메서드는 언제 사용하느냐?
이유도 없이 남발해서 사용하면 RC의 존재가 정말 몇번 참조 되었는지 세는 게 아니라
개발자 짠 코드 멋대로 될 수도 있지 않음??
따라서 retain을 사용하는 경우는 정해져 있음
우리가 ARC에서 자동으로 RC 값이 증가하던 경우를 떠올리셈
제일 큰 경우를 생각하면
새로 인스턴스를 만들 때
기존 인스턴스를 참조할 때
이잖음?
근데 MRC에선 새로 인스턴스를 만드는 건 retain 메서드를 호출하지 않아도
ARC처럼 자동으로 되는 걸 위에서 확인 했음
자 그럼 기존 인스턴스를 참조할 때는 어떨지 봐볼 것임
위와 같은 코드를 실행하면
메모리는 이렇게 생김
자, 자세히 보면 ARC와 다른 점이 있음
ARC의 경우 test2가 test의 인스턴스 주소값을 새로 할당받았기 때문에
자동으로 RC + 1이 되는 것을 저번 포스팅에서 확인 했음
근데 MRC의 경우엔 자동으로 RC가 증가하지 않음
위 코드를 실행하고 retainCount를 출력해보면
test의 인스턴스를 가리키는 새로운 변수(test2)가 생겼음에도
RC는 올라가지 않음 ㅎㅎㅎㅎ
왜냐 ?
Manual!! 수동이닊하..🌝
자, 그래서 위처럼 만약 인스턴스를 새로 생성하는 경우를 제외하고,
인스턴스의 주소값을 할당받은 경우 (인스턴스에 대한 소유권을 가진 경우)
RC를 올려 줄 retain 작업을 이때 손.수 해주어야 함
이런 식으루!!!!!!
이렇게 하면
RC가 올라가고
이제 ARC와 같이 이런 그림이 되는 것임 ㅎ_ㅎ
자, 근데 retain 함수의 원형을 보면
반환 타입이 InstanceType임..
이말인 즉!! retain 함수 자체가 자기 자신(인스턴스)의 주소값을 반환한다는 것임
따라서 다음과 같이 더욱 간단하게 쓸 쑤 있음
이런 식으루..
당연히 test, test2의 RC를 출력해 보면
나란히 2가 되어 있음ㅎㅎㅎ
test, test2 둘은 같은 인스턴스를 가리키기 때문에
같은 retainCount 프로퍼티를 참조하고 있응께 ㅎ_ㅎ
어려운 내용이 아니기 때문에 모두 이해가 갔을 거라 믿음 XD
1-2. 참조 횟수 Count Down (-)
이번엔 RC를 직접 감소해줘야 하는 경우에 대해 알아볼 것임
매우 간단하게 함수 하나만 쓰면 됨 ~_~
Release |
이또한 마찬가지로 ARC에서 RC가 감소되는 시점에
직접 Release 메서드를 써주면 됨
이 부분에 관해선 ARC처럼 엄청 자세히 다루지 않고,
예제 하나만 보고 넘어가겠셈
자 다음과 같이 인스턴스를 생성하여 retain 했음
다음과 같이 RC가 2인 상태임
이때 만약 내가 test2를 더이상 사용하지 않아서
test2에 nil을 대입 할 것임
자 이렇게 대입하면, ARC의 경우 자동으로 RC가 -1될 것임
그런데 MRC는 입이 아프도록 말했듯이 수동임
따라서 RC는 계속 2로 유지 될 것임
이렇게 말이지
따라서 release 메서드를 호출해야
RC 값을 감소시킬 수 있음
자 이렇게 해주면
우리가 원하는 RC값이 1이 됨
이제 이 다음에 우리가 원하는 작업인
nil을 대입해주면 됨
쨔쟌...... 끝!!!!!!!!!!!!!
2. MRC 쓰지 마세욤...
MRC는 ARC가 나오기 이전 구식 방법일 뿐더러..
저걸 언제 다 손수 해주고 있어........... 코드도 진짜 지저분해짐..
또한 애플 문서를 보면 말이지.......
retainCount의 경우... *autorelease pool에 의해
release가 지연된 Count를 갖고있을 수 있어서
유용한 정보를 얻을 수 있는 방법이 매 우 낮 다 고함
(*autrelease pool이란 ARC에서도 가끔 쓰는데, 메모리 해제를 RC값과 상관 없이
pool block이 끝나는 지점에서 한번에 처리할 떄 사용함)
고러니..!!!!!!!!!!!!!!!!!
그냥 간편한 ARC 쓰자 🥶
저 같은 경우는 legacy 코드에 아직 MRC의 잔재들이 좀 남아있어서
개념 정리 겸 공부 했지만
대충... 알아두셔도.. 사실 모르셔도..... 될듯...;;ㅁ;;
autoreleasepool에 대한 건 시간나면 포스팅...
합..니다.. 안녕...
혹시나 틀리거나 궁금한 점 제발 댓글좀..
'iOS > iOS' 카테고리의 다른 글
iOS) UIView 테두리 만들기 (2) | 2020.10.20 |
---|---|
iOS) 진동 울리기 (0) | 2020.10.15 |
iOS) 메모리 관리 (2/3) - strong , weak, unowned, 순환 참조 (11) | 2020.09.09 |
iOS) 메모리 관리 (1/3) - ARC(Automatic Reference Counting) (26) | 2020.09.07 |
iOS) 메모리 구조 (Code, Data, Stack, Heap) (25) | 2020.09.02 |